Перейти к публикации

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

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

Zer0Galaxy

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

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

ВOOOOOOOOOOOOOOT!!!! НАКОНЕЦ!!!!! СПАСИБО, ДМИТРИЙ!!!!   ЭТО ЭПИК!!!!

Еще и с параметрами запуск! Могу это только сравнить с полетом Гагарина в космос высадкой американцев на Луну. Дождались. Фуууууух! Это может и маленький шажок для программистов всего человечества , но огромный шаг для работы с модом ОС! Спасибо, Дима, за титаническую работу!

Дима, не знаю, как тебя благодарить даже!

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


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

Ценою неимоверных усилий удалось портировать уже известную вам библиотеку thread в ОС.

Библиотека доступна для скачивания по команде

pastebin get E0SzJcCx thread.lua

По сравнению с версией для СС, библиотека имеет еще две функции, вызываемых без параметров:

thread.init() - инициализирует многозадачный режим. Должна вызываться один раз перед вызовом других функций библиотеки.

thread.waitForAll() - ожидает завершения всех дочерних потоков.

Функции create, kill и killAll работают аналогично версии для СС.

 

Пример работы с библиотекой:

local thread = require("thread")
-- Инициализируем многозадачность
thread.init()
-- Функция, которая выводит строку str несколько раз с интервалом секунда
function foo(str,n)
  for i=1,n do
    print(str)
    os.sleep(1)
  end
end
-- Запускаем два экземпляра функции с разными параметрами
thread.create(foo,"AAA",5)
thread.create(foo,"BBB",7)
-- Ждем завершения
thread.waitForAll()

Результат работы программы

attachicon.giftest.png

У меня 2 вопроса:

1 - thread'ы убиваются сами после завершения функции или их надо убивать в ручную?

2 - Можно ли убивать thread'ы вручную не дожидаясь их завершения?

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


Ссылка на сообщение
Поделиться на других сайтах
У меня 2 вопроса:

1 - thread'ы убиваются сами после завершения функции или их надо убивать в ручную?

2 - Можно ли убивать thread'ы вручную не дожидаясь их завершения?

1. Насильного убийства не присходит. Когда функция завершается, её поток принимает статус "dead" автоматически, после чего он исключается из списка активных потоков и удаляется сборщиком мусора.

2. Да. Для этого нужно сохранить значение, возвращаемое функцией create, и вызвать kill

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


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

Было бы очень хорошо, если бы ты документировал все API в этой теме. Как что называется, что делает и что возвращает. в деталях.

Плюс привел несколько примеров использования

 

Я реально буду её использовать для своей управления с андроида , уже думал, что придется свое писать, но еще не приступил к написанию. Прямо подарок судьбы

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


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

Давным давно пользуюсь либой под СС, чень удобно!

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


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

Было бы очень хорошо, если бы ты документировал все API в этой теме. Как что называется, что делает и что возвращает. в деталях.

Плюс привел несколько примеров использования

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

 

Давным давно пользуюсь либой под СС, чень удобно!

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

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


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

Документацию пожалуйста.

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


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

В исходном коде я не могу понять, откуда " _timeout " взялось (берется), кто его присваивает или я что-то упустил?

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


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

Это максимальное время ожидания события. Оно указывается при вызове функций computer.pullSignal, os.sleep или event.pull

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


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

Это максимальное время ожидания события. Оно указывается при вызове функций computer.pullSignal, os.sleep или event.pull

А каким образом оно передает. Как я понял когда "сопрограмма" выполняет os.sleep(), то она каким-то образом переходит в другую программу, но как она передает _timeout ?

 

Имел ввиду, что при вызове computer.pullSignal, os.sleep(), event.pull что происходит дальше? 

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

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


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

Это вопрос не к библиотеке thread, а к библиотеке coroutin. Когда сопрограмма вызывает os.sleep, фактически вызывается coroutin.yield (см. исходник os). При этом управление передается ядру системы. В качестве параметра передается таймаут. Ядро возвращает управление сопрограмме либо по получению сигнала либо по прошествии таймаута. При использовании thread происходит тоже самое, только роль ядра для дочерних потоков играет основной поток.

  • Like 2

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


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

Возникла проблема при попытке сделать поток с «computer.pullSignal()» если не указывать время ожидания, то библиотека выдает ошибку, что я попыталась сравнить string and number. Но можно просто установить таймер на подольше и будет все отлично)

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

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


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

Возникла проблема при попытке сделать поток с «computer.pullSignal()» если не указывать время ожидания, то библиотека выдает ошибку, что я попыталась сравнить string and number. Но можно просто установить таймер на подольше и будет все отлично)

Благодарю за багрепорт. Исправлено.

Скачайте либу по той же ссылке.

  • Like 1

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


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

Почему он мертв?)

 

/lib/thread.lua:28: cannot resume dead coroutine

...

 

Какие ошибочные действия могли привести к этому?

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


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

 

/lib/thread.lua:28: cannot resume dead coroutine

...

 

Какие ошибочные действия могли привести к этому?

Походу поток завершится успел, а ты его пытаешься возобновить

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


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

Походу поток завершится успел, а ты его пытаешься возобновить

Как это решить?

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


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

Код в студию

local thread = require("thread");

thread.init()

local function f1()
  print("hello1");
end;

local function f2()
    thread.create(f2)
    thread.create(f1);
    print("hello2");
end;

thread.create(f2);
thread.waitForAll();
Изменено пользователем Pavel52

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


Ссылка на сообщение
Поделиться на других сайтах
local thread = require("thread");

thread.init()

local function f1()
  print("hello1");
end;

local function f2()
    thread.create(f2)
    thread.create(f1);
    print("hello2");
end;

thread.create(f2);
thread.waitForAll();

Не пойму, чего ты этим хотел добиться. Если тело потока не содержит бесконечных циклов и вызовов pullSignal, то такой поток выполняется целиком после чего благополучно умирает. Т.е. твой код можно с успехом заменить на 

local function f1()
  print("hello1");
end;

local function f2()
    f2()
    f1();
    print("hello2");
end;

f2();

Только по идее вылететь мы должны были по переполнению памяти.

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


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

Не пойму, чего ты этим хотел добиться. Если тело потока не содержит бесконечных циклов и вызовов pullSignal, то такой поток выполняется целиком после чего благополучно умирает. Т.е. твой код можно с успехом заменить на 

local function f1()
  print("hello1");
end;

local function f2()
    f2()
    f1();
    print("hello2");
end;

f2();

Только по идее вылететь мы должны были по переполнению памяти.

 

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

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


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

Никогда не используй рекурсию с целью создания бесконечного цикла. Для этого существует while true do

  • Like 1

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


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

А как же быть с функциями, которые возвращают что-нибудь?

  • Like 1

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


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

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

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

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


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

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

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

Я даже не знаю, как это реализовать. Пример event.pull(), которая приостанавливает цикл(в моем случае).

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


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

Я, похоже, не правильно понял вопрос. О каких функциях идет речь и какие значения они должны возвращать? Если можно, пример кода

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


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

Я, похоже, не правильно понял вопрос. О каких функциях идет речь и какие значения они должны возвращать? Если можно, пример кода

Ну вот пример. Мне нужно выводить какое-то значение на экран, которое постоянно изменяется. И параллельно принимать сигнал от event.pull(), чтобы можно было взаимодействовать. Ибо во время вызова этой функции приостанавливается программа.

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

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


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

Ну вот пример. Мне нужно выводить какое-то значение на экран, которое постоянно изменяется. И параллельно принимать сигнал от event.pull(), чтобы можно было взаимодействовать. Ибо во время вызова этой функции приостанавливается программа.

Используй event.lister() Он обрабатывает сигналы в режиме ожидания os.sleep(). Таким образом можешь что угодно выводить, но поставить хотя бы os.sleep(0) которого будет достаточно, чтобы обработать эвенты.

 

Например так:

function func()
<код>
end

event.lister("key_down",func) --регистрируем эвент и привязываем события "нажатие клавиши" функцию func()

while true do
print(42) --выводим на экран что хотим
os.sleep(1) --обрабатываем эвенты
end

event.ignore("key_down",func) --убираем эвент
Изменено пользователем qwertyMAN

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


Ссылка на сообщение
Поделиться на других сайтах
Используй event.lister() Он обрабатывает сигналы в режиме ожидания os.sleep(). Таким образом можешь что угодно выводить, но поставить хотя бы os.sleep(0) которого будет достаточно, чтобы обработать эвенты.

 

Например так:

function func()
<код>
end

event.lister("key_down",func) --регистрируем эвент и привязываем события "нажатие клавиши" функцию func()

while true do
print(42) --выводим на экран что хотим
os.sleep(1) --обрабатываем эвенты
end

event.ignore("key_down",func) --убираем эвент

Благодарю!

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


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

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

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

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

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

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

Войти

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

Войти сейчас

×