Перейти к публикации
Новости
  • В ближайшее время постараюсь разобраться с картой сервера/ЛК/бб кодами
  • Новости
Zer0Galaxy

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

Рекомендованные сообщения

Многопоточность в CraftOS легко реализуется при помощи стандартной библиотеки parallel. Способ этот отличается простотой и может быть использован даже начинающими программистами. Чего уж проще? Оформи каждый поток в виде отдельной функции и вызови waitForAll или waitForAny.

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

Во-первых, пока работает parallel, основная нить программы приостанавливается и занимается исключительно обслуживанием параллельных потоков.

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

В-третьих, после запуска такая параллельность не контролируема. Отсутствует возможность принудительно прервать какой либо из потоков или добавить к уже существующим еще один.

 

Несколько иную многопоточность можно реализовать при помощи библиотеки thread, доступной по адресу http://pastebin.com/32S4HssH

Библиотека содержит три функции:

thread.create(f , ...) - создает поток, который сразу же начинает выполняться параллельно основному потоку. При желании можно создать серию потоков, вызвав функцию create несколько раз подряд. В качестве параметра f необходимо указать функцию, содержащую тело потока. После f  можно указать параметры, передаваемые ей.

Функция create возвращает вновь созданный поток как объект типа нить ("thread"). Значение это может понадобиться если вы захотите прервать принудительно созданный поток.

thread.kill(co) - прерывает выполнение параллельного потока. co - завершаемый поток, значение, полученное при вызове функции create.

thread.killAll() - прекращает выполнение всех параллельных потоков, за исключением основного. Вызывать эту функцию полезно перед завершением программы. В противном случае действующие потоки продолжат свою работу даже после выхода из программы.

  • Like 8

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Ух ты, отличная библиотека, а главное удобная-то какая в работе! Спасибо, Зеро)

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Спасибо, Дима, огромное, библиотека супер! Слов нет, одни слюни. Ты просто маг Луа! :D :smile9:

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Пользуйтесь осторожно. Библиотека еще не обкатана.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Как обстоят дела с критическими точками и состоянием гонки?

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
Как обстоят дела с критическими точками и состоянием гонки?
Э! А это что такое?

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Как обстоят дела с критическими точками и состоянием гонки?

А эти проблемы актуальны для сопрограмм Lua?

Проблема может возникнуть при неправильном проектировании программы (например доступа к файлу), но это уже проблема программиста а не библиотеки. Или я ошибаюсь?

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
А эти проблемы актуальны для сопрограмм Lua?

Проблема может возникнуть при неправильном проектировании программы (например доступа к файлу), но это уже проблема программиста а не библиотеки. Или я ошибаюсь?

Конечно. Ошибаешься.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Конечно. Ошибаешься.

Аргументацию в студию! Пожалуйста.

Хочу разобраться с этим вопросом.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Аргументацию в студию! Пожалуйста.

Хочу разобраться с этим вопросом.

если пишешь либу для других программистов,нужно писать нормально,а ты пишешь под себя.(Помнишь либу socket).Zer0Galaxy правильно делает.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

если пишешь либу для других программистов,нужно писать нормально,а ты пишешь под себя.(Помнишь либу socket).Zer0Galaxy правильно делает.

А. Я не об этом. Я о том, можно ли говорить о проблеме состояния гонки и критических точек применимо к сопрограммам (coroutine) Lua. Исключая те случаи, когда косяк возник по вине программиста.

  • Like 1

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Хочу знать, что делает вот это: os.pullEventRaw=SingleThread или os.pullEventRaw=MultiThread. Получается то, что мы присваиваем "не понимаю чему, но судя по названию пулу" pullEventRaw указатель на функцию SingleThread или MultiThread? Почему и зачем это нужно?

А так же зачем нужно делать вот это:

if coroutine.status( co ) == "dead" then
 filter[co],co=nil,next(filter,co)
else

То есть, если подпрограмма остановлена, то получаем список её аргументов из filters. Затем удаляем указатель на подпрограмму, чтобы её потом скушал сборщик мусора. Затем получаем следующие аргументы для последующей подпрограммы. Зачем нужно получать аргументы подпрограммы co если эти полученные значения в данный момент не используются? Или тут какое то хитромудреное присваивание? Просто я никак не могу понять, что эта строка делает...

Изменено пользователем JaggerDer

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Хочу знать, что делает вот это: os.pullEventRaw=SingleThread или os.pullEventRaw=MultiThread. Получается то, что мы присваиваем "не понимаю чему, но судя по названию пулу" pullEventRaw указатель на функцию SingleThread или MultiThread? Почему и зачем это нужно?

os.pullEventRaw это стандартная процедура, через которую приложение Lua получает события. Обычно текст этой процедуры соответствует тексту процедуры SingleThread. Но в многопоточном режиме приложение должно не только получать события, но и передавать их в дочерние процессы. Этим занимается процедура MultiThread, поэтому pullEventRaw перенаправляем на нее.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

А так же зачем нужно делать вот это:

if coroutine.status( co ) == "dead" then
 filter[co],co=nil,next(filter,co)
else

То есть, если подпрограмма остановлена, то получаем список её аргументов из filters. Затем удаляем указатель на подпрограмму, чтобы её потом скушал сборщик мусора. Затем получаем следующие аргументы для последующей подпрограммы. Зачем нужно получать аргументы подпрограммы co если эти полученные значения в данный момент не используются? Или тут какое то хитромудреное присваивание? Просто я никак не могу понять, что эта строка делает...

Если сопрограмма остановлена, то исключаем ее из списка 

 filter[co]=nil

и берем следующую

 co=next(filter,co)

Но если сделать именно так, то получим исключку т.к. filter[co] к этому моменту уже не существует.

Можно было бы сделать через промежуточную переменную:

 co1=next(filter,co)
 filter[co]=nil
 co=co1

но тогда никто бы не поверил, что я умею программировать на Lua. Поэтому я использовал параллельное присваивание (см. http://www.lua.ru/doc/2.4.3.html)

Изменено пользователем Zer0Galaxy
  • Like 4

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Создайте аккаунт или войдите в него для комментирования

Вы должны быть пользователем, чтобы оставить комментарий

Создать аккаунт

Зарегистрируйтесь для получения аккаунта. Это просто!

Зарегистрировать аккаунт

Войти

Уже зарегистрированы? Войдите здесь.

Войти сейчас

×