Многопоточность в Lua - PullRequest
       23

Многопоточность в Lua

9 голосов
/ 05 июня 2010

Я разговаривал с моим другом на днях. Я говорил, что в чистом Lua вы не можете создать упреждающую многозадачную систему. Он утверждает, что вы можете, по следующей причине:

Как в C, так и в Lua нет встроенных библиотек потоков [примечание OP: ну, Lua технически, но AFAIK не годится для наших целей]. Windows, написанная в основном на C (++), имеет преимущественную многозадачность, которую они создали с нуля. Следовательно, вы должны быть в состоянии сделать то же самое в Lua. Большая проблема, с которой я сталкиваюсь, заключается в том, что основной способ работы вытесняющей многозадачности (насколько мне известно) состоит в том, что он генерирует регулярные прерывания, которые менеджер использует для получения контроля и определения того, над каким кодом он должен работать дальше. Я также не думаю, что у Луа есть какое-либо средство, способное сделать это.

Мой вопрос таков: Можно ли написать библиотеку на чистом Lua, которая позволяет людям иметь преимущественную многозадачность?

Ответы [ 3 ]

7 голосов
/ 05 июня 2010

Я не понимаю, как это сделать, хотя без формальной семантики Lua (например, семантики yield) действительно трудно придумать железный аргумент, почему это невозможно сделать. (Я хотел формальную семантику для возрастов , но, очевидно, у Роберто и Лхф есть дела поважнее.)

Если бы я хотел превентивную многозадачность для Lua, я бы даже не попытался сделать это в чистом Lua. Вместо этого я бы использовал старый трюк, который впервые увидел 20 лет назад в Standard ML of New Jersey:

  • Прерывание устанавливает флаг в lua_State о том, что «текущая сопрограмма была выгружена».

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

Этот патч будет легко написать и легко поддерживать. Это не решает проблему долгосрочной функции C, которая не может быть прервана, но если вам нужно решить эту проблему, вы переходите на гораздо более сложную территорию, и вы можете также делать все свои потоки в уровень C, а не уровень Lua.

5 голосов
/ 10 февраля 2012

Нет. Невозможно написать упреждающий планировщик на чистом Lua. В какой-то момент упреждающий планировщик нуждается в каком-то механизме, таком как подпрограмма обработки прерываний, чтобы отобрать управление у текущего потока и передать его планировщику, который затем может передать его другому потоку. Чистый Луа не имеет этого механизма.

Вы упоминаете, что Windows написана в основном на C / C ++. Ключевое слово в основном. Вы не можете написать упреждающий планировщик на чистом ANSI C / C ++. Обычно часть процедуры обработки прерываний написана на ассемблере. Или компилятор C / C ++ реализует нестандартное расширение, которое позволяет программам обработки прерываний записываться на C / C ++. Некоторые компиляторы позволяют вам объявлять функции с модификатором __interrupt, который заставляет компилятор генерировать пролонгацию / эпилог, который позволяет использовать функцию в качестве подпрограммы обработки прерывания.

Кроме того, код, который устанавливает подпрограмму обработки прерываний, работает с регистрами ЦП с отображенным в памяти вводом-выводом или инструкциями ввода-вывода. Ни один из этого кода не является переносимым ANSI C / C ++. И, зависит от архитектуры процессора.

5 голосов
/ 05 июня 2010

Не то, что я знаю, нет. Было бы почти абсурдно просто, если бы вы могли уступать через ловушки, установленные в сопрограммах с помощью debug.sethook, но это не работает. Вы можете получить доход от C-хуков, установленных из C (lua_sethook), но я не могу понять точно , чтобы сделать это, и это не чистый Lua в любом случае.

Даже если бы это было возможно, это не было бы истинным потоком. Например, все будет работать в том же потоке операционной системы. Ваш хук будет учитывать множество факторов (таких как время, возможно, память и т. Д.), А затем определять, следует ли уступать. Затем поддавшийся сопрограмм решал, какой дочерний сопрограмм будет работать следующим. Вам также необходимо решить, когда следует вызывать хук. Чаще всего встречается на каждой инструкции Lua, но это влечет за собой снижение производительности. И если сопрограмма вызывает функцию C, у Lua нет юрисдикции. Если этот вызов C занимает много времени, вы ничего не можете с этим поделать.

Здесь - связанная ветка из списка рассылки Lua-L, которая может вас заинтересовать.

...