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 ……