Глобальная переменная и многопоток.

one

Client
Регистрация
22.09.2015
Сообщения
6 793
Благодарностей
1 264
Баллы
113
В шаблоне, в самом его начале, стоит экшен увеличения значения ГП. Далее экшен получения значения из ГП и экшен внесения изменения в ГП. По логике (моей), при старте в многопотоке, первый запустившийся поток его меняет, все следующие уже берут значение измененное предыдущим потоком. На деле выходит что все потоки первый раз берут одно и тоже значение и уже далее как и предполагалось, значение измененное предыдущим поток. Такое ощущение что все потоки стартуют разом.

Не совсем понятно, почему при старте шаблона так происходит. Проясните ситуацию кто в состоянии.
 

doc

Client
Регистрация
30.03.2012
Сообщения
8 607
Благодарностей
4 598
Баллы
113
потому что некоторые потоки ломятся к глобалке одновременно. Это дело нужно лочить в коде
 
  • Спасибо
Реакции: one

one

Client
Регистрация
22.09.2015
Сообщения
6 793
Благодарностей
1 264
Баллы
113
Подскажи примером для экшенов.
 

doc

Client
Регистрация
30.03.2012
Сообщения
8 607
Благодарностей
4 598
Баллы
113
экшенами не залочить. Только код
 
  • Спасибо
Реакции: one

nomarketing

Client
Регистрация
01.11.2013
Сообщения
907
Благодарностей
178
Баллы
43
В шаблоне, в самом его начале, стоит экшен увеличения значения ГП. Далее экшен получения значения из ГП и экшен внесения изменения в ГП. По логике (моей), при старте в многопотоке, первый запустившийся поток его меняет, все следующие уже берут значение измененное предыдущим потоком. На деле выходит что все потоки первый раз берут одно и тоже значение и уже далее как и предполагалось, значение измененное предыдущим поток. Такое ощущение что все потоки стартуют разом.

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

try catch C#
 

one

Client
Регистрация
22.09.2015
Сообщения
6 793
Благодарностей
1 264
Баллы
113
А какое действие лочить. кото
экшенами не залочить. Только код
Ты мне как то давал пример сниппета многопоточной реализации. Попробую на нем реализовать.
 
Последнее редактирование:

doc

Client
Регистрация
30.03.2012
Сообщения
8 607
Благодарностей
4 598
Баллы
113
лочить за один заход увеличение и получение значения
 

sydoow

Client
Регистрация
22.06.2011
Сообщения
277
Благодарностей
141
Баллы
43

one

Client
Регистрация
22.09.2015
Сообщения
6 793
Благодарностей
1 264
Баллы
113
Вот решения для работы с глобальной переменной в многопотоке. В данном случаем ГП выступает как счетчик. Может кому пригодиться.

Исходное значение ГП должно быть равно 0. Данным сниппетом увеличиваем его на 1 и кладем результат в локальную переменную. Далее, в шаблоне уже работаем с этой локальной переменной.
Код:
lock(SyncObject) {
  try {
  var gb_count = project.GlobalVariables["threads", "variable_name"];
  return ++gb_count.Value;
  }
  catch (KeyNotFoundException ex) {
  project.GlobalVariables.SetVariable("threads", "variable_name", 1);
  return 1;
  }
}
И если надо по достижению определенного значения в глобальной переменной зациклить работу шаблона, то сбрасываем ее на 0 этим сниппетом и начинаем все по новой:
Код:
lock(SyncObject){
    project.GlobalVariables.SetVariable("threads", "variable_name", 0);
}
Комментарии приветствуются!
 

one

Client
Регистрация
22.09.2015
Сообщения
6 793
Благодарностей
1 264
Баллы
113
В процессе тестирования, выявилось, что если в ZP прервать работу шаблона и потом запустить его по новой, то потоки берут одинаковые значения в самом начале работы. Далее уже идут как положено. Перезагрузив ZP, работа потоков идет корректно до следующего прерывания работы шаблона. В чем может быть причина?

upload_2017-6-5_12-21-24.png
 

ol1ver

Client
Регистрация
29.08.2013
Сообщения
332
Благодарностей
82
Баллы
28
я поставил себе apache на локалке и сделал простой скрипт на php
обращаемся к странице -> увеличиваем значение +1 -> сохраняем в файл значение -> выводим

Суть какая, пока идет запись (один из потоков обратился к странице), последующие обращения к скрипту не дадут записывать


p.s - очень редко, но порой counter сбрасывался на 0 (может от 70и потоков захлебывался). + подстраховывался - записывал последний ID в файл LastID_rand-1-100.txt и сортировал по дате изменения (на случай если cчетчик сбрасывался)

нужно создать файл counter.txt и выставить права 777
<?php

$f=fopen("counter.txt","a+");// Открываем файл на добавление.
/* Если открыть просто на запись,
то после ftruncate() придется делать fseek() на начало файла
*/
flock($f,LOCK_EX); // блокируем файл
$counter=fgets($f)+1; // читаем значение счетчика и увеличиваем его на единицу
ftruncate($f,0); // обнуляем файл
fputs($f,$counter); // пишем новое значение счетчика
echo $counter; // выводим на экран счетчик
flock($f,LOCK_UN); // снимаем блокировку (необязательно, ибо сама снимется при закрытии)
fclose($f); // закрываем
?>
 
Последнее редактирование:
  • Спасибо
Реакции: one

one

Client
Регистрация
22.09.2015
Сообщения
6 793
Благодарностей
1 264
Баллы
113
Ну я как бы решил для работы в многопотоке со списками (списки храню в БД) воспользоваться стандартными средствами зенки. Видимо тут какие то костыли у нее. Ну или у меня руки кривые. Хотя по логике построено все правильно.
 

one

Client
Регистрация
22.09.2015
Сообщения
6 793
Благодарностей
1 264
Баллы
113
Такс... В общем в процессе написания шаблона и тестирования многопотока выявились кое какие недостатки выше обозначенной реализации.

1. Нужно запускать шаблон в много потоке сразу (указав нужное кол-во потоков) а не по одному (см. п2).
2. Если в процессе работы шаблона понадобилось добавить поток(и), ГП обнуляется и весь процесс начинает работу с начала.

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

P.S. Во что я ввязался... :D
 
Последнее редактирование:

nomarketing

Client
Регистрация
01.11.2013
Сообщения
907
Благодарностей
178
Баллы
43
Такс... В общем в процессе написания шаблона и тестирования многопотока выявились кое какие недостатки выше обозначенной реализации.

1. Нужно запускать шаблон в много потоке сразу (указав нужное кол-во потоков) а не по одному (см. п2).
2. Если в процессе работы шаблона понадобилось добавить поток(и), ГП обнуляется и весь процесс начинает работу с начала.

Пришел к выводу, что для реализации казалось бы тривиальной задачи, которые должны как бы решаться встроенными инструментами ZP, придется прибегнуть к сторонним решениям. Думаю дальше будет больше. Как пример, планируется запоминать на каком ID шаблон закончил свою работу и при последующем запуске начинать еuо работу с этого ID.

P.S. Во что я ввязался... :D
Напиши логику.
А то мало ли.
Я помню свою битву с потоками, изначально я вобще не правильно их понимал, потом мне гонщик обьяснил как они работают, я думал потоки это что то стабильное, но нет :-) просто нужно их лочик, что бы они не работали одновременно с одним файлом, когда ты их лочиш у тебя есть возможность ими в какой то степени манипулировать.
Не пойму где проблема, обьявляешь глобальный счетчик, запускаешь к примеру сразу 5 потоков с локом, (работа с базой, файлами) и все.
На счет добавление потоков не знаю, я такими изврящениями не занимался.
На счет запоминания айди, просто сделай в базе поле current id и туда после отработки с файлов, пиши номер, т.е каждый поток после прохода по файлу - базе, будет писать туда айди. (отталкиваясь от глобального счетчика)
 

one

Client
Регистрация
22.09.2015
Сообщения
6 793
Благодарностей
1 264
Баллы
113
nomarketing, не, есть там проблема, ты не до конца ее понимаешь т.к. у тебя не установлен соответствующий (секретный) патч для работы с потоками. Попробуй то, что ты предложил проработать с изначальным значением 0 в ГП. Это значение, будет означать что шаблон не запускался ни разу т.е. мы его написали, отладили и начинаем работу.
 

one

Client
Регистрация
22.09.2015
Сообщения
6 793
Благодарностей
1 264
Баллы
113
Так как полностью перешел на работу с БД в итоге пришлось переделать всю логику шаблоне. В много потоке столкнулся с той же проблемой, несколько потоков успевают схватить одни и те же данные. Решение правда на экшенах - получаем данные-записываем данные. Пробовал конвертировать в C#, но что то перестает работать после конвертации. Посему прошу помощи подсказать решение на C# для многопотока получить из указанной БД, таблицы, ячейки значение. Для тестирования мне пока хватить этого.
На счет запоминания айди, просто сделай в базе поле current id
На этом остановился. :-)
 
Регистрация
26.05.2020
Сообщения
461
Благодарностей
164
Баллы
43

one

Client
Регистрация
22.09.2015
Сообщения
6 793
Благодарностей
1 264
Баллы
113

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