English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
المعاونة Lua (coroutine) تشبه إلى حد كبير السينكروني:تملك ذاكرة مستقلة،متغيرات محلية مستقلة،مؤشر أوامر مستقل،وتشارك مع协同 أخرى في متغيرات عالمية وغيرها من الأشياء
المعاونة هي ميزة قوية جدًا،لكنها معقدة جدًا أيضًا في الاستخدام
الفرق الرئيسي بين السينكروني والمعاونة هو أن برنامجًا يحتوي على عدة سينكروني يمكنه تشغيل عدة سينكروني في نفس الوقت،بينما المعاونة تحتاج إلى التشغيل التكافلي
في أي لحظة معينة،يُشغل فقط协同程序 واحد،والمعاونة التي تشغلها تُستدعى إلى الاستقالة بشكل واضح
المعاونة تشبه إلى حد كبير السينكروني المتبادل بين عدد من السينكروني في نفس الخيط،وفي نفس الوقت تشبه المعاونة.
الطريقة | وصف |
---|---|
coroutine.create() | إنشاء coroutine،يعود ب coroutine،الم参数 هو فункциة،عندما تستخدم مع resume،تُستيقظ دعوة الفункциة |
coroutine.resume() | إعادة تشغيل coroutine،استخدامها مع create |
coroutine.yield() | إيقاف coroutine،تضبط coroutine في حالة الاستقالة،ويمكن استخدامها مع resume للحصول على تأثيرات مفيدة |
coroutine.status() | مراجعة حالة coroutine ملاحظة:للمعرفة الوقت الذي يكون فيه حالة coroutine واحدة من هذه الحالات: dead،suspended،running،يرجى الرجوع إلى البرنامج أدناه |
coroutine.wrap() | إنشاء coroutine،يعود بفункциة،إذا قمت بتشغيل هذه الفункциة،ستدخل coroutine،ويعاد فيها استخدام ميزة create |
coroutine.running() | Returns the running coroutine, a coroutine is a thread, when using running, it returns the thread number of a coroutine |
-- coroutine_test.lua file co = coroutine.create( function(i) print(i); end ) coroutine.resume(co, 1) -- 1 print(coroutine.status(co)) -- dead print("----------") co = coroutine.wrap( function(i) print(i); end ) co(1) print("----------") co2 = coroutine.create( function() for i = 1, 10 do print(i) if i == 3 then print(coroutine.status(co2)) -- running print(coroutine.running()) -- thread:XXXXXX end coroutine.yield() end end ) coroutine.resume(co2) -- 1 coroutine.resume(co2) -- 2 coroutine.resume(co2) -- 3 print(coroutine.status(co2)) -- suspended print(coroutine.running()) print("----------")
نتائج تنفيذ الأمثلة أعلاه هي:
1 dead ---------- 1 ---------- 1 2 3 running thread: 0x7fb801c05868 false suspended thread: 0x7fb801c04c88 true ----------
From coroutine.running, it can be seen that coroutine is implemented as a thread at the bottom level.
When creating a coroutine, it is equivalent to registering an event in a new thread.
When using resume to trigger an event, the coroutine function created by create is executed, and when encountering yield, it represents pausing the current thread and waiting for the next resume to trigger the event.
Next, we analyze a more detailed example:
function foo(a) print("foo function output", a) return coroutine.yield(2 * a) -- returns the value of 2*a end co = coroutine.create(function (a , b)} print("إخراج تنفيذ البرنامج المتعاوني الأول", a, b) -- co-body 1 10 local r = foo(a + 1) print("إخراج تنفيذ البرنامج المتعاوني الثاني", r) local r, s = coroutine.yield(a + b, a - b) -- قيم a،b هي التي تم تمريرها عند الدعوة الأولى للبرنامج المتعاوني print("إخراج تنفيذ البرنامج المتعاوني الثالثة", r, s) return b, "إنهاء برنامج التعاون" -- قيمة b هي التي تم تمريرها عند الدعوة الثانية للبرنامج المتعاوني end) print("main", coroutine.resume(co, 1, 10)) -- true, 4 print("--خط فاصل----") print("main", coroutine.resume(co, "r")) -- true 11 -9 print("---خط فاصل---") print("main", coroutine.resume(co, "x", "y")) -- true 10 انتهاء print("---خط فاصل---") print("main", coroutine.resume(co, "x", "y")) -- لا يمكن استيقاظ البرنامج المتوقف print("---خط فاصل---")
نتائج تنفيذ الأمثلة أعلاه هي:
إخراج تنفيذ البرنامج المتعاوني الأول 1 10 إخراج foo الوظيفة 2 main true 4 --خط فاصل---- إخراج تنفيذ البرنامج المتعاوني الثاني r main true 11 -9 ---خط فاصل--- إخراج تنفيذ البرنامج المتعاوني الثالثة x y main true 10 إنهاء برنامج التعاون ---خط فاصل--- main false لا يمكن استيقاظ البرنامج المتوقف ---خط فاصل---
المثال السابق يستمر كما يلي:
دعوة resume لاستيقاظ برنامج التعاون، العودة بنجاح لـ resume هي true، وإلا false؛
تنفيذ برنامج التعاون;
التنفيذ حتى جملة yield;
إيقاف برنامج التعاون باستخدام yield، والعودة الأولى باستخدام resume;(ملاحظة: هنا، العودة باستخدام yield هي معلمات resume)
الاستيقاظ الثاني لبرنامج التعاون؛(ملاحظة: 参数 resume باستثناء الأولي، سيتم استخدام الباقي كمعلمات yield)
استمرار yield في العودة;
استمرار التعاونية في العمل؛
إذا استمرت التعاونية في العمل بعد إكمالها وإعادة التطبيق لأسلوب resume فإن النتيجة ستكون: cannot resume dead coroutine
قوة تعاون resume و yield تكمن في أن resume يتواجد في البرنامج الرئيسي، حيث يدخل الحالة الخارجية (البيانات) إلى التعاونية الداخلية؛ بينما يعيد yield الحالة الداخلية (البيانات) إلى البرنامج الرئيسي.
الآن سأستخدم coroutine Lua لحل المشكلة الكلاسيكية لمشكلة المنتج والمستهلك.
local newProductor function productor() local i = 0 while true do i = i + 1 send(i) -- إرسال البضاعة المنتجة إلى المستهلك end end function consumer() while true do local i = receive() -- الحصول على البضاعة من المنتج print(i) end end function receive() local status, value = coroutine.resume(newProductor) return value end function send(x) coroutine.yield(x) -- x يشير إلى القيمة التي يجب إرسالها، بعد إرسال القيمة، يتم تعليق التعاونية end -- بدء البرنامج newProductor = coroutine.create(productor) consumer()
نتائج تنفيذ الأمثلة أعلاه هي:
1 2 3 4 5 6 7 8 9 10 11 12 13 ……