Latest web development tutorials

Lua coroutines (coroutine)

Apa yang dimaksud dengan sinergis (coroutine)?

Lua coroutines (coroutine) Thread relatif sama: tumpukan independen, variabel lokal memisahkan, independen instruksi pointer, tetapi variabel global juga berbagi, dan hal-hal lain dan program kolaboratif lainnya.

Synergy sangat kuat, tetapi juga sangat rumit untuk digunakan.

Perbedaan antara benang dan coroutines

Perbedaan utama antara benang dan coroutines bahwa program memiliki beberapa benang dapat menjalankan beberapa thread secara bersamaan, sementara program koperasi akan membutuhkan sekitar kolaborasi lain.

Pada waktu tertentu hanya ada satu program kerjasama berjalan, dan coroutine berjalan hanya diminta untuk menghapus waktu ditangguhkan akan ditangguhkan.

program kolaborasi agak mirip dengan sinkronisasi beberapa thread di thread yang sama menunggu kunci beberapa thread kolaborasi agak mirip.

Dasar sintaks

cara deskripsi
coroutine.create () Buat coroutine, coroutine kembali, argumen adalah fungsi, ketika digunakan bersama dengan, dan dilanjutkan bila panggilan fungsi bangun
coroutine.resume () Restart coroutine, dan menciptakan dengan penggunaan
coroutine.yield () Ditangguhkan coroutine, yang coroutine ke tertunda negara dan melanjutkan dengan penggunaan ini memiliki banyak efek yang berguna
coroutine.status () Periksa status coroutine CATATAN: Negara coroutine, ada tiga: mati, menangguhkan, berjalan, terutama ketika ada keadaan seperti itu, silakan lihat prosedur berikut
coroutine.wrap () Buat coroutine, mengembalikan fungsi bahwa sekali Anda memanggil fungsi ini, masukkan coroutine, dan menciptakan fungsi pengulangan
coroutine.running () Pengembalian menjalankan coroutine, coroutine adalah thread, ketika berjalan ketika benang adalah untuk mengembalikan sejumlah corouting

Contoh berikut menunjukkan penggunaan masing-masing metode 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("----------")

Contoh pelaksanaan output di atas adalah:

1
dead
----------
1
----------
1
2
3
running
thread: 0x7fb801c05868	false
suspended
thread: 0x7fb801c04c88	true
----------

coroutine.running dapat dilihat, implementasi coroutine adalah thread di bagian bawah.

Ketika membuat coroutine ketika acara terdaftar di thread baru.

Ketika acara lamaran dipicu ketika, membuat fungsi coroutine dijalankan, dan ketika dihadapkan dengan yield atas nama menunda thread saat menunggu lagi melanjutkan memicu event.

Selanjutnya, kami menganalisis contoh yang lebih rinci:

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("---分割线---")

Contoh pelaksanaan output di atas adalah:

第一次协同程序执行输出	1	10
foo 函数输出	2
main	true	4
--分割线----
第二次协同程序执行输出	r
main	true	11	-9
---分割线---
第三次协同程序执行输出	x	y
main	true	10	结束协同程序
---分割线---
main	false	cannot resume dead coroutine
---分割线---

Contoh mengambil alih sebagai berikut:

  • Sebut melanjutkan, akan berkoordinasi wakeup, melanjutkan keberhasilan operasi return true, jika tidak kembali palsu;
  • Program berjalan kolaboratif;
  • Jalankan untuk menghasilkan laporan;
  • Hasil ditangguhkan coroutine kembali melanjutkan pertama; (Catatan: yield return sini untuk melanjutkan parameter adalah parameter)
  • melanjutkan kedua, bangun lagi Coroutines; (Catatan: parameter melanjutkan ini, selain argumen pertama, parameter yang tersisa akan menghasilkan sebagai parameter)
  • hasil pengembalian;
  • program kolaborasi terus berjalan;
  • Jika Anda terus menjalankan program koperasi menggunakan metode terus memanggil melanjutkan setelah selesainya output: tidak dapat melanjutkan coroutine mati

Kekuatan tempat dengan bahwa resume dan hasil, melanjutkan di program utama, itu akan menjadi luar negara (data) dilewatkan ke prosedur koordinasi internal, dan akan menghasilkan keadaan internal (data) kembali ke proses utama.


masalah konsumen - produsen

Konsumen dari masalah klasik ini - saya sekarang akan menyelesaikan produsen menggunakan Lua coroutines.

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()

Contoh pelaksanaan output di atas adalah:

1
2
3
4
5
6
7
8
9
10
11
12
13
……