Lua Coroutines

Neste artigo, exploraremos as corrotinas Lua , como elas funcionam e como usá-las efetivamente em seus programas Lua.

As corrotinas são um recurso poderoso da linguagem de programação Lua que permite escrever código assíncrono em um estilo síncrono.

Usando uma co-rotina em Lua, você pode pausar e retomar uma função.

Uma co-rotina executa a função que você especifica, assim como uma chamada de função normal . No entanto, ao contrário das funções regulares, uma corrotina pode ser executada a qualquer momento, permitindo que outra corrotina assuma o controle.



O que são Lua Coroutines?

As co-rotinas são um tipo especial de função Lua que pode devolver o controle ao chamador enquanto mantém seu próprio estado.

Isso permite que várias corrotinas sejam executadas simultaneamente no mesmo encadeamento Lua.

Quando uma co-rotina cede, ela suspende sua execução e retorna um valor ao chamador.

O chamador pode retomar a co-rotina posteriormente, passando um novo valor a ser usado na próxima iteração da co-rotina.


Funções Lua Cor-Rotina

A biblioteca de corrotinas fornece várias funções que permitem criar, retomar e produzir corrotinas.

Funções de corrotina Visão geral
coroutine.create(f) Cria uma nova co-rotina com a função f. Quando a co-rotina for retomada pela primeira vez, a função f será executada.
coroutine.resume(co, …) Retoma a co-rotina passada como argumento. Se a co-rotina foi suspensa antes, ela continua a execução de onde parou. Os argumentos opcionais passados ​​para resumir são os valores a serem passados ​​para a co-rotina como argumentos. Se a co-rotina não foi suspensa antes, o resumo começa no início.
coroutine.yield(…) Suspende a co-rotina e retorna ao chamador. A função yield retorna os argumentos passados ​​para a chamada de retomada quando a co-rotina é retomada novamente.
coroutine.status(co) Retorna o status da co-rotina passada como argumento. Os valores possíveis são “ suspenso ”, “em execução”, “morto” ou “normal”.
coroutine.wrap Cria uma nova co-rotina e retorna uma função que a retoma quando chamada. Pode ser usado como uma alternativa mais simples para coroutine.create e coroutine.resume .
coroutine.running Este método retorna o objeto da co-rotina que está em execução no momento ou nil se for chamado do thread principal.
coroutine.isyieldable Retorna um booleano que indica se a co-rotina atual pode ser cedida. Com coroutine.wrap , as corrotinas não podem ceder e sempre retornarão false.

O exemplo a seguir é implementado usando os métodos coroutine.create , coroutine.resume() , coroutine.yield() , coroutine.status() , coroutine.running() e coroutine.isyieldable() em Lua:

Example: 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
local function safeYield()
if coroutine.isyieldable() then
coroutine.yield("It's safe to yield now")
print("coroutine.yield is executed")
print("\n")
else
print("It's not safe to yield now")
end
end
local function printCurrentCoroutine()
local currentCoroutine = coroutine.running()
if currentCoroutine then
print("Current coroutine:", currentCoroutine)
else
print("Not in a coroutine")
end
end
-- define a coroutine function
local myCoroutine = coroutine.create(function()
local i = 1
while i <= 3 do
print("Coroutine count: "..i)
printCurrentCoroutine()
safeYield()
i = i + 1
end
end)
-- start the coroutine
coroutine.resume(myCoroutine)
-- get the status of the coroutine
local status = coroutine.status(myCoroutine)
print("Coroutine status: "..status)
-- resume the coroutine
coroutine.resume(myCoroutine)
-- get the status of the coroutine
status = coroutine.status(myCoroutine)
print("Coroutine status: "..status)
-- resume the coroutine
coroutine.resume(myCoroutine)
-- get the status of the coroutine
status = coroutine.status(myCoroutine)
print("Coroutine status: "..status)
-- resume the coroutine (should fail)
coroutine.resume(myCoroutine)
-- get the status of the coroutine
status = coroutine.status(myCoroutine)
print("Coroutine status: "..status)
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

O código acima define duas funções, safeYield e printCurrentCoroutine, e a função lua co-rotina chamada myCoroutine. Ele cria uma nova corrotina e a executa com coroutine.resume, chamando a função safeYield que verifica se é seguro ceder e retorna a corrotina.

O código verifica o status da co-rotina após cada retomada usando coroutine.status e imprime o status. A co-rotina executa três iterações e depois finaliza, portanto, ao ser retomada novamente, gera um erro e o status é impresso como “morto”.

O exemplo a seguir mostra como usar a função lua coroutine.wrap :

Example: 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
-- define a regular function that takes two arguments and returns their sum
function add(a, b)
return a + b
end
-- wrap the add function in a coroutine
local co = coroutine.wrap(add)
-- call the coroutine with arguments and retrieve the result
local result = co(5, 4)
-- print the result
print(result)
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
Se nosso conteúdo causou impacto em você, espalhe a notícia nas mídias sociais e informe outras pessoas!
Nós valorizamos o seu feedback.
+1
1
+1
0
+1
0
+1
0
+1
0
+1
0
+1
0

Assine a nossa newsletter
Digite seu e-mail para receber um resumo semanal de nossos melhores posts. Saber mais!
ícone