Latest web development tutorials

corrutinas Lua (co-rutina)

¿Qué es un sinérgico (co-rutina)?

Lua corrutinas (corrutina) Tema relativamente similares: una pila independiente, las variables locales se separan, el puntero de instrucción independiente, pero también variables globales compartidas, y la mayoría de otras cosas y otros programas de colaboración.

La sinergia es muy potente, pero también muy complicado de usar.

La diferencia entre las roscas y corrutinas

La diferencia principal entre los hilos y co-rutinas que un programa tiene varios hilos se pueden ejecutar varios hilos simultáneamente, mientras que el programa de cooperación necesitaría alrededor de otra colaboración.

En cualquier momento dado hay sólo un programa de cooperación está en marcha, y sólo la co-rutina se ejecuta ser requerido para borrar el tiempo suspendido será suspendido.

programa de colaboración algo similar para sincronizar múltiples hilos en el mismo hilo en espera de la cerradura varias roscas de colaboración algo similar.

La sintaxis básica

camino descripción
coroutine.create () Crear una co-rutina, corrutina volver, el argumento es una función, cuando se usa en conjunto con, y reanudará cuando las llamadas de función de despertador
coroutine.resume () Reinicie co-rutina, y crear con el uso de
coroutine.yield () corrutina suspendida, la co-rutina de estado pendiente y reanudar con el uso de esta opción para que una gran cantidad de efecto útil
coroutine.status () Comprobar el estado de corrutina NOTA: Estado co-rutina, hay tres: muertos, suspender, correr, sobre todo cuando hay un estado tal, por favor refiérase a los siguientes procedimientos
coroutine.wrap () Crear una co-rutina, devuelve una función que una vez que se llama a esta función, introduce co-rutina, y crear la función de repetición
coroutine.running () Las devoluciones se ejecutan co-rutina, una co-rutina es un hilo, cuando se ejecuta cuando el hilo es devolver un número de corouting

El siguiente ejemplo demuestra el uso de cada uno de los métodos anteriores:

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

Los ejemplos de la aplicación de la salida anterior es:

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

coroutine.running puede observarse, la aplicación co-rutina es un hilo en la parte inferior.

Cuando crear una co-rutina cuando un evento se ha registrado en el nuevo hilo.

Cuando se desencadena un evento de reanudación cuando, cree que se ejecuta una función de co-rutina, y cuando se enfrentan con el rendimiento en nombre suspende el subproceso actual que esperar de nuevo reanudar el evento de activación.

A continuación, analizamos un ejemplo más detallado:

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

Los ejemplos de la aplicación de la salida anterior es:

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

Los ejemplos se hicieron cargo de la siguiente manera:

  • Reanudación de la llamada, coordinará de activación, reanudar el funcionamiento exitoso regreso cierto, si no return false;
  • programa se ejecuta en colaboración;
  • Corre para rendir declaraciones;
  • rendimiento suspendido co-rutina vuelve primera hoja de vida; (Nota: el rendimiento de retorno aquí para reanudar parámetros son parámetros)
  • Segunda hoja de vida, estela corrutinas de nuevo; (Nota: Los parámetros de este resumen, además del primer argumento, el resto de parámetros producirá como parámetro)
  • retornos de rendimiento;
  • programa de colaboración continúa funcionando;
  • Si sigue para ejecutar el programa de cooperación utiliza el método sigue llamando hoja de vida después de la finalización de la salida: no se puede reanudar corrutina muertos

El poder del lugar con la hoja de vida y el rendimiento, curriculum vitae en el programa principal, que será fuera del estado (datos) que pasan a los procedimientos de coordinación interna, y rendirá estado interno (datos) devuelve al proceso principal.


problemas de los consumidores - Productor

Los consumidores de este problema clásico - Ahora voy a completar los productores utilizan corrutinas 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()

Los ejemplos de la aplicación de la salida anterior es:

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