Latest web development tutorials

coroutines Lua (coroutine)

O que é um sinérgico (coroutine)?

Lua coroutines (coroutine) Tópico relativamente semelhantes: uma pilha de independentes, as variáveis ​​locais separados, ponteiro de instrução independente, mas variáveis ​​globais também compartilhados, ea maioria das outras coisas e outros programas de colaboração.

Synergy é muito poderoso, mas também muito complicado de usar.

A diferença entre fios e coroutines

A principal diferença entre fios e co-rotinas que um programa tem vários segmentos podem ser executados vários threads simultaneamente, enquanto programa de cooperação seria necessário cerca de uma outra colaboração.

Em um determinado momento existe apenas um programa cooperativo está em execução e a co-rotina executando apenas ser obrigado a limpar o tempo suspenso será suspensa.

programa de colaboração algo semelhante para sincronizar vários segmentos no mesmo segmento aguardando o bloqueio de vários segmentos de colaboração algo semelhante.

A sintaxe básica

caminho descrição
coroutine.create () Criar uma co-rotina, voltar co-rotina, o argumento é uma função, quando usado em conjunto com, e retomada quando as chamadas de função de despertador
coroutine.resume () Reiniciar co-rotina e criar com o uso de
coroutine.yield () coroutine suspenso, a co-rotina de estado pendente e continuar com o uso desta para ter um monte de efeito útil
coroutine.status () Verifique o status do co-rotina NOTA: estado co-rotina, existem três: morto, suspender, em execução, especialmente quando existe um tal estado, por favor consulte os seguintes procedimentos
coroutine.wrap () Criar uma co-rotina, retorna uma função que depois de chamar essa função, digite co-rotina, e criar a função de repetição
coroutine.running () Retornos estão em execução co-rotina, uma co-rotina é um fio, quando executado quando o segmento é retornar um número de corouting

O exemplo seguinte demonstra o uso de cada um dos métodos acima:

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

Exemplos da implementação da saída acima é:

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

coroutine.running pode ser visto, a aplicação co-rotina é uma rosca na parte inferior.

Ao criar uma co-rotina quando um evento é registrado no novo segmento.

Quando um evento currículo é acionado quando, criar uma função de co-rotina é executada, e quando confrontado com o rendimento em nome suspende o segmento atual de esperar novamente retomar fato gerador.

Em seguida, analisamos um exemplo mais detalhado:

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

Exemplos da implementação da saída acima é:

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

Exemplos assumiu como segue:

  • Chamada currículo, vai coordenar excitação, retomar a operação de retorno bem sucedido verdade, caso contrário return false;
  • dirige o programa de colaboração;
  • Corra para produzir declarações;
  • rendimento suspenso coroutine primeira resume retorna; (Nota: rendimento retorno aqui para retomar os parâmetros são parâmetros)
  • Segundo currículo, acordar de novo co-rotinas; (Nota: parâmetros este currículo, além de o primeiro argumento, os parâmetros restantes vai render como um parâmetro)
  • rendimento retornos;
  • programa de colaboração continua a ser executado;
  • Se você continuar a executar o programa de cooperativa usa o método continua a chamar currículo após a conclusão da saída: não é possível retomar coroutine mortos

O poder do lugar com o currículo e de rendimento, currículo no programa principal, será fora do estado (dados) passado para os procedimentos de coordenação interna, e vai render estado interno (dados) retorna para o processo principal.


questões de consumo - Produtor

Consumidores deste problema clássico - Agora vou completar os produtores utilizam coroutines 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()

Exemplos da implementação da saída acima é:

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