Latest web development tutorials

coroutine Lua (coroutine)

Che cosa è un sinergico (coroutine)?

Lua coroutine (coroutine) Discussione relativamente simili: uno stack autonomo, le variabili locali separati, puntatore all'istruzione indipendente, ma anche le variabili globali condivise, e la maggior parte delle altre cose e di altri programmi di collaborazione.

Synergy è molto potente, ma anche molto complicato da usare.

La differenza tra i thread e coroutine

La differenza principale tra fili e co-routine che un programma ha più thread possono eseguire più thread contemporaneamente, mentre il programma di cooperazione avrebbe bisogno di un altro collaborazione.

In qualsiasi momento c'è solo un programma di cooperazione è in esecuzione, e l'esecuzione coroutine essere richiesto solo per cancellare il tempo sospeso sarà sospeso.

programma di collaborazione in qualche modo simile per sincronizzare più thread nello stesso thread in attesa che i diversi fili di blocco in qualche modo simile collaborazione.

La sintassi di base

modo descrizione
coroutine.create () Creare un coroutine, tornare coroutine, argomento è una funzione, se usato in combinazione con, e riprendere quando le chiamate di funzione sveglia
coroutine.resume () Riavviare coroutine, e creare con l'uso di
coroutine.yield () coroutine Sospeso, il coroutine di stato di attesa e riprendere con l'uso di questo per avere un sacco di effetto utile
coroutine.status () Controllare lo stato di coroutine NOTA: stato coroutine, ci sono tre: morti, sospendere, in esecuzione, in particolare quando vi è un tale stato, si prega di fare riferimento ai seguenti procedure
coroutine.wrap () Creare un coroutine, restituisce una funzione che una volta che si chiama questa funzione, entra coroutine, e creare funzione di ripetizione
coroutine.running () I ritorni sono in esecuzione coroutine, un coroutine è un filo, quando in esecuzione quando il filo è quello di restituire un numero di corouting

Il seguente esempio illustra l'utilizzo di ciascuno dei metodi di cui sopra:

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

Esempi di attuazione dell'uscita sopra è:

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

coroutine.running può essere visto, coroutine attuazione è un filo in basso.

Quando creare un coroutine quando un evento è registrato nel nuovo thread.

Quando un evento di ripristino viene attivato quando, creare viene eseguita una funzione coroutine, e di fronte alla resa per conto sospende il thread corrente aspettare ancora riprendere la innescando eventi.

Avanti, analizziamo un esempio più dettagliato:

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

Esempi di attuazione dell'uscita sopra è:

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

Esempi ha assunto come segue:

  • Ripristino chiamata, coordinerà sveglia, riprendere l'operazione ritorno di successo vero, altrimenti return false;
  • corre programma di collaborazione;
  • Eseguire a cedere dichiarazioni;
  • resa sospeso coroutine rendimenti primo curriculum, (Nota: resa ritorno qui per riprendere i parametri sono parametri)
  • Secondo CV, wake coroutine nuovamente; (Nota: parametri Questo riprendere, oltre al primo argomento, i rimanenti parametri produrrà come parametro)
  • i rendimenti dei rendimenti;
  • programma di collaborazione continua a funzionare;
  • Se si continua a eseguire il programma di cooperazione utilizza il metodo continua a chiamare riprendere dopo il completamento della produzione: non può riprendere il coroutine morti

Il potere del luogo con quel curriculum e la resa, riprendere nel programma principale, sarà al di fuori dello stato (dati) passati alle procedure di coordinamento interno, e produrrà stato (dati) interno ritorna al processo principale.


questioni relative ai consumatori - Produttore

I consumatori di questo classico problema - io ora completare i produttori utilizzano 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()

Esempi di attuazione dell'uscita sopra è:

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