Latest web development tutorials

Lua сопрограмм (сопрограмма)

Что такое синергетический (сопрограммная)?

Lua сопрограмм (сопрограммная) Тема относительно схожи: независимый стек, локальные переменные разделяются, независимый указатель команд, но и общие глобальные переменные, и большинство других вещей и другие совместные программы.

Синергия является очень мощным, но и очень сложно использовать.

Разница между нитями и сопрограммам

Основное различие между потоками и сопрограммам, что программа имеет несколько потоков может запускать несколько потоков одновременно, в то время как совместная программа будет нуждаться о другом сотрудничестве.

В любой момент времени существует только одна совместная программа работает, и работает сопрограммная требуется только, чтобы очистить приостановленного времени будет приостановлено.

Совместная программа несколько похожа на синхронизации нескольких потоков в одном потоке ожидает блокировки нескольких потоков несколько аналогичных сотрудничества.

Базовый синтаксис

способ описание
coroutine.create () Создание сопрограмму, возвращение сопрограмму, аргумент является функцией, при использовании в сочетании с, и возобновляется, когда вызовы функций пробуждения
coroutine.resume () Перезапуск сопрограмму, а также создавать с использованием
coroutine.yield () Подвесной сопрограммная, подпрограмма в состоянии ожидания и возобновить с использованием этого, чтобы иметь много полезного эффекта
coroutine.status () Проверьте состояние сопрограммное ПРИМЕЧАНИЕ: сопрограмму состояние, есть три: мертвы, приостанавливать, бег, особенно, когда есть такое состояние, пожалуйста, обратитесь к следующим процедурам
coroutine.wrap () Создание сопрограмму, возвращает функцию, которая, как только вы вызвать эту функцию, введите сопрограмму, и создать функцию повтора
coroutine.running () Возвращения работает сопрограмму, сопрограмма является нитью, при запуске, когда поток должен вернуться ряд corouting

Следующий пример демонстрирует использование каждого из указанных выше способов:

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

Примеры реализации вышеуказанной продукции является:

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

coroutine.running можно увидеть, сопрограммная реализация является нитью в нижней части.

При создании сопрограмму когда событие регистрируется в новом потоке.

Когда событие резюме срабатывает, когда, создать сопрограммная функция выполняется, и когда они сталкиваются с доходностью от имени приостанавливает текущий поток ждать снова возобновить запускающее событие.

Далее мы анализируем более подробный пример:

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

Примеры реализации вышеуказанной продукции является:

第一次协同程序执行输出	1	10
foo 函数输出	2
main	true	4
--分割线----
第二次协同程序执行输出	r
main	true	11	-9
---分割线---
第三次协同程序执行输出	x	y
main	true	10	结束协同程序
---分割线---
main	false	cannot resume dead 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()

Примеры реализации вышеуказанной продукции является:

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