Lua coroutine
Apakah coroutine?
Lua coroutine adalah serupa dengan utas: ia mempunyai tindanan bebas, pembolehubah tempatan bebas dan penunjuk arahan bebas, sambil berkongsi pembolehubah global dan kebanyakan perkara lain dengan coroutine lain.
Kolaborasi ialah fungsi yang sangat berkuasa, tetapi ia juga sangat rumit untuk digunakan.
Perbezaan antara thread dan coroutine
Perbezaan utama antara thread dan coroutine ialah program dengan berbilang thread boleh menjalankan beberapa thread pada masa yang sama, manakala coroutine perlu dijalankan dengan kerjasama setiap lain.
Hanya satu coroutine sedang berjalan pada bila-bila masa dan coroutine yang sedang berjalan hanya akan digantung apabila diminta untuk menggantung secara jelas.
Coroutine agak serupa dengan berbilang benang yang disegerakkan dan beberapa utas menunggu kunci benang yang sama agak serupa dengan kerjasama.
Tatabahasa Asas
方法 | 描述 |
---|---|
coroutine.create() | 创建coroutine,返回coroutine, 参数是一个函数,当和resume配合使用的时候就唤醒函数调用 |
coroutine.resume() | 重启coroutine,和create配合使用 |
coroutine.yield() | 挂起coroutine,将coroutine设置为挂起状态,这个和resume配合使用能有很多有用的效果 |
coroutine.status() | 查看coroutine的状态 注:coroutine的状态有三种:dead,suspend,running,具体什么时候有这样的状态请参考下面的程序 |
coroutine.wrap() | 创建coroutine,返回一个函数,一旦你调用这个函数,就进入coroutine,和create功能重复 |
coroutine.running() | 返回正在跑的coroutine,一个coroutine就是一个线程,当使用running的时候,就是返回一个corouting的线程号 |
Contoh berikut menunjukkan penggunaan setiap kaedah di atas:
-- coroutine_test.lua 文件 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("----------")
Output pelaksanaan contoh di atas ialah:
1 dead ---------- 1 ---------- 1 2 3 running thread: 0x7fb801c05868 false suspended thread: 0x7fb801c04c88 true ----------
Ia boleh dilihat daripada coroutine.running bahawa asas pelaksanaan coroutine ialah benang.
Apabila membuat coroutine, acara didaftarkan dalam urutan baharu.
Apabila resume digunakan untuk mencetuskan acara, fungsi coroutine create dilaksanakan Apabila hasil ditemui, ini bermakna menggantung urutan semasa dan menunggu resume untuk mencetuskan acara itu semula.
Seterusnya kami menganalisis contoh yang lebih terperinci:
function foo (a) print("foo 函数输出", a) return coroutine.yield(2 * a) -- 返回 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 end print("---分割线---") print("main", coroutine.resume(co, "x", "y")) -- cannot resume dead coroutine print("---分割线---")
Output pelaksanaan contoh di atas ialah:
第一次协同程序执行输出 1 10 foo 函数输出 2 main true 4 --分割线---- 第二次协同程序执行输出 r main true 11 -9 ---分割线--- 第三次协同程序执行输出 x y main true 10 结束协同程序 ---分割线--- main false cannot resume dead coroutine ---分割线---
Contoh di atas diteruskan seperti berikut:
Panggil resume untuk membangunkan coroutine Operasi resume kembali benar jika berjaya, jika tidak ia kembali palsu
Coroutine berjalan; 🎜>
Jalankan ke penyata hasil;- hasil menutup coroutine, dan resume pertama kembali; (Nota: pulangan hasil di sini, dan parameter adalah parameter resume )
- Sambung semula untuk kali kedua dan bangunkan coroutine semula; (Nota: Antara parameter resume di sini, kecuali untuk parameter pertama, parameter yang selebihnya akan digunakan sebagai parameter hasil)
- hasil pulangan;
- Coroutine terus berjalan; untuk menjalankan dan terus memanggil kaedah resume selepas selesai, kemudian Output: tidak boleh menyambung semula coroutine mati
- Gabungan kuat resume dan hasil ialah resume sedang dalam proses utama, dan ia lulus status luaran (data) ke dalam coroutine; dan hasil Status dalaman (data) dikembalikan kepada proses utama.
Masalah Pengeluar-Pengguna
Kini saya menggunakan coroutine Lua untuk menyelesaikan masalah pengeluar-pengguna klasik.
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()
Hasil keluaran contoh di atas ialah:
1 2 3 4 5 6 7 8 9 10 11 12 13 ……