Автокликер Clickermann :: Форум
Основной раздел => Общие вопросы => Topic started by: i0 on November 19, 2014, 08:38:21 PM
-
2 потока включаемые в процессе работы скрипта
При начале действий в одном из них ставится глобальный флаг занятости, другой поток должен ждать снятия флага.
Но иногда в начале работы этого не происходит, и оба потока начинают действия одновременно (позже всё устаканивается).
Считал, прочтя описание, что это невозможно. Как избежать такой ситуации?
[spoiler=код]thread(t1, 0)
if ( $bBusy )
logwrite( "t1: жду" )
wait( 1 )
else
$bBusy = 1
logwrite( "t1: работа 5 c..." )
wait( 5 )
logwrite( "t1: ... завершена" )
$bBusy = 0
wait( 2 )
end_if
end_thread
thread(t2, 0)
if ( $bBusy )
logwrite( " t2: жду" )
wait( 1 )
else
$bBusy = 1
logwrite( " t2: работа 7 c..." )
wait( 7 )
logwrite( " t2: ... завершена" )
$bBusy = 0
wait( 2 )
end_if
end_thread
logshow(1)
logclear
$bBusy = 0
wait(1)
logwrite( "start threads" )
//wait(1)
setthread (t1, 1)
setthread (t2, 1)
while (1)
wait( 10 )
end_cyc
halt
[/spoiler]
[spoiler=лог]20:16:59 start threads
20:16:59 t1: работа 5 c...
20:16:59 t2: работа 7 c...
20:17:04 t1: ... завершена
20:17:06 t2: ... завершена
20:17:06 t1: работа 5 c...
20:17:08 t2: жду
20:17:09 t2: жду
20:17:10 t2: жду
20:17:11 t1: ... завершена
20:17:11 t2: работа 7 c...
20:17:13 t1: жду
20:17:14 t1: жду
20:17:15 t1: жду
20:17:16 t1: жду
20:17:17 t1: жду
20:17:18 t2: ... завершена
20:17:18 t1: работа 5 c...
20:17:20 t2: жду
20:17:21 t2: жду
20:17:22 t2: жду
20:17:23 t1: ... завершена
20:17:23 t2: жду
20:17:24 t2: работа 7 c...
20:17:25 t1: жду
[/spoiler]
-
Я думаю, потому, что при старте они синхронно вскакивают внутрь условия. Т.е. успевают проверить переменную $bBusy до того как она станет 1 в другом потоке. Ведь код в начале одинаковый и время выполнения одинаковое.
Достаточно один из потоков при старте чуть тормознуть
thread(t2, 0)
WAITMS(5)
...
лог:
9:55:42 start threads
9:55:42 t1: работа 5 c...
9:55:42 t2: жду
9:55:43 t2: жду
9:55:44 t2: жду
9:55:45 t2: жду
9:55:47 t2: жду
9:55:47 t1: ... завершена
9:55:48 t2: работа 7 c...
9:55:49 t1: жду
9:55:50 t1: жду
9:55:51 t1: жду
9:55:52 t1: жду
9:55:53 t1: жду
9:55:54 t1: жду
9:55:55 t2: ... завершена
9:55:55 t1: работа 5 c...
5 мс - ничто... Можно тормознуть и при старте
setthread (t1, 1)
WAITMS(5)
setthread (t2, 1)
-
вот я тоже опытным путём пришёл к wait при старте
но если "они синхронно ... успевают проверить переменную $bBusy до того как она станет 1 в другом потоке", где гарантия, что такая ситуация не может повториться в процессе работы?
-
Если у тебя одна переменная для проверки на все потоки то никаких гарантий. Сам себя загнал в угол. Не может быть рассинхронизации абсолютной, рано или поздно потоки сойдутся в выполнении на 1 итерацию, по грубым подсчетам каждые 63 сек.
Хотя судя по скрипту я вообще не пойму зачем эти потоки, у тебя выполняется один поток, во время его выполнения второй должен останавливаться, не проще это сделать обычным способом? Одна подпрограмма, потом другая, они и так по-очереди выполнятся будут.
-
Если у тебя одна переменная для проверки на все потоки то никаких гарантий.
Хотя судя по скрипту я вообще не пойму зачем эти потоки, у тебя выполняется один поток, во время его выполнения второй должен останавливаться
модули скрипта, которые хочу реализовать через потоки, предназначены для разных действий в игре.
каждое действие имеет свой независимый период ожидания
действия технически не могут быть вызываны одновременно
да, мою задачу можно реализовать без потоков (как уже сделано), но с потоками, имеющими собственные таймеры, всё гораздо красивее в коде
-
Красивей то красивей, но как то не по людски. Сначала ввести параллельность, а потом героически с ней бороться. Потоки только ради использования потоков... сомнительно.
Красивее будет вывести в подпрограммы и отдельный переборщик таймеров в цикле. Всё удобно искать и настраивать.
-
Красивее будет вывести в подпрограммы и отдельный переборщик таймеров в цикле. Всё удобно искать и настраивать.
так уже реализовано. теперь хочу поизвращаться с применением потоков
-
Тогда лучше выбрать более подходящую задачу.