Как грамотно организовать многопоточный режим

sitnem

Client
Регистрация
03.12.2016
Сообщения
122
Благодарностей
78
Баллы
28
Написал чекер динамичных данных, суть в том, чтобы ухватить нужные изменения. Необходимо сделать интервал проверки, как можно меньше. Запустил в многопотоке, работает ожидаемо криво: между некоторыми потоками интервал минимальный, зато между другими огромный (по меркам задачи), а некоторые потоки вообще сплетаются, и чекают в один момент, т.е. по сути один из них стреляет в холостую. Ну чистый рандом в общем, всё логично.

Какие могут быть варианты? Можно ли тут нечто подобие очереди организовать? Скажем первый поток дошел до точки N, делает проверку ушел ли кто-то в течении 3 секунд с этой точки, если нет - ждет, как-то только прошло 3 сек, продолжает работу, если несколько потоков подошли к точки N, то соответственно так же пускать их очередью.

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

В общем, буду благодарен за помощь.
 

Вложения

zortexx

Client
Регистрация
19.09.2011
Сообщения
2 520
Благодарностей
1 226
Баллы
113
Лучше использовать СУБД и ее внутренние возможности, но можно обойтись и таблицей, правда всю логику нужно будет воспроизводить в шаблоне.

Заводите дополнительное поле в которое помещается статус строки. Например, 1 - в обработке, а 0 - свободен. Таким образом, при взятии строки и ее обработке вам будет известно состояние строки.

На небольших объемах, достаточно разместить строки так чтобы они не повторялись и следить чтобы потоков было меньше чем строк в документе. Однако тут есть множество нюансов, и обобщенной рекомендации не существует.
 
Последнее редактирование:
  • Спасибо
Реакции: sitnem

sitnem

Client
Регистрация
03.12.2016
Сообщения
122
Благодарностей
78
Баллы
28
Отпишу решение. Может кому-то когда-нибудь будет полезно.

Пришел к выводу, что очередь при моем количестве потоков не нужна (у меня 5-15 потоков максималка), реализовал работу по маркеру, на моменте остановки потоков (точки синхронизации; в моменте, где образуется очередь) реализовал бесконечный цикл, который ловит маркер (глобальную переменную, которая ровняется 0), после чего сразу назначает глобальной переменной значение 1 (чтобы другие потоки не могли его захватить), после чего открывает маркер (назначает ему значение 0) через пару действий в шаблоне, и так далее. Теперь коллизий потоков нет, и интервал уже не плавающий, а с очевидным МО, и незначительным отклонением.

Код:
Код:
lock(SyncObject) {
try {
var gbVar = project.GlobalVariables["mynamespace", "marker"];
} catch (KeyNotFoundException ex) {
project.GlobalVariables.SetVariable("mynamespace", "marker", "0");
return "Global variable is initialized";
}
}
return "Already initialized";
Код:
for (int j=1;;j++) {
        if (project.GlobalVariables["mynamespace", "marker"].ToString()=="0"){
        project.GlobalVariables.SetVariable("mynamespace", "marker", "1"); // Забираем маркер
        break;
        }
project.SendWarningToLog("Поток " + project.Variables["UserNumber"].Value + ": ЖДУ МАРКЕР", true);
Thread.Sleep(100);
}
Код:
project.GlobalVariables.SetVariable("[email protected]", "marker", "0");

Последний выполняется на определенном экшене, но думаю, что чуть позже реализую временной маркер.
 
  • Спасибо
Реакции: evgen_po

Кто просматривает тему: (Всего: 1, Пользователи: 0, Гости: 1)