Перейти к содержимому
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 происходит тоже самое, только роль ядра для дочерних потоков играет основной поток.

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


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

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

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

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


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

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

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

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

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


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

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

 

/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();

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

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


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

Присоединяйтесь к обсуждению

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

Гость
Ответить в тему...

×   Вы вставили отформатированное содержимое.   Удалить форматирование

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отобразить как ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.


×
×
  • Создать...