Шаблон - "охраняющий локкер" - или как можно залочить блоки кубиков

  • Автор темы Автор темы arhip1985
  • Дата начала Дата начала

arhip1985

Client
Регистрация
31.10.2011
Сообщения
3 052
Реакции
796
Баллы
113
Всем привет)
ничего супер-пупер - шаблон-схема, но как-то встала у меня задача - залочить часть кубиков, для последовательного выполнения потоками именно в определённых местах шаблона.

Последовательность действий, на примере:
1. Создаём глобальную переменную shab_name , пространство имён называем "глобал".
создаём глобальную переменную.jpg


2.устанавливаем значение по умолчанию = 0

3.Перед входом в охраняемый для последовательной работы блок кода, ставим кубик C# - назавём его "вход в охраняемую зону" , со следующим кодом:
C#:
Развернуть Свернуть Копировать
lock(SyncObject)] {
  if(project.GlobalVariables["глобал", "shab_name"].Value==0){
project.GlobalVariables.SetVariable("глобал", "shab_name", 1);
    return "зашёл 1 поток";
}
    else throw new Exception();

}


4. По зелёной ветке с этого кубика - заходим в охраняемый от многопотока блок

3. По красной ветке с этого кубика - выходим на кубик с требуемой паузой - этот кубик с паузой можно назвать - "изолятор", и зелёную ветку с паузы бросаем обратно на "вход в охраняемую зону"

4. Все ветки выходящие из охраняемого блока пропускаем через следующий кубик C#, назовём его - "выход из охраняемой зоны":
Код:
Развернуть Свернуть Копировать
lock(SyncObject) {
project.GlobalVariables.SetVariable("глобал", "shab_name", 0);
return "можно заходить другим";
}

Схема конструкции:

схема охраняющий локкер.jpg



Шаблон прикрепил. Можно запустить в многопотоке и по логу увидеть его работу.

Успешных всем разработок!


Казалось бы - всё интуитивно просто и понятно)
!Однако, после публикации поста - подтянулись старожилы и доказали мне наглядно, что данная схема в таком виде не сработает (хотя проводя тесты - эта схема была успешной в данном виде - но как оказалось из-за совпавших обстоятельств).
Благодарен Doc и iBred за поворот головы в нужную сторону.

Выкладываю исправление:

2. В нашу глобальную переменную никакое значение не записываем - ни по-умолчанию, вообще никак - это мы сделаем внутри кубика, поскольку запись в по-умолчанию у глобальных переменных работает не очевидно.

3. перед входом в охраняемый блок ставим такой код, вместо того что ранее выкладывал:
C#:
Развернуть Свернуть Копировать
lock(SyncObject)] {
if(project.GlobalVariables["глобал", "shab_name"].Value==null){
     project.GlobalVariables.SetVariable("глобал", "shab_name", 0);
   } //это и есть наша запись в переменную по-умолчанию - означаящая записать число 0, только если в этой переменной ничего нет, если уже есть - то будет пропущено
  if(project.GlobalVariables["глобал", "shab_name"].Value==0){
project.GlobalVariables.SetVariable("глобал", "shab_name", 1);
    return "зашёл 1 поток";
}
    else throw new Exception();

}

Всё остальное оставляем как было раньше. Прикладываю исправленный шаблон, называется - охраняющий локкер правильный.
 

Вложения

Последнее редактирование:
мне всегда казалось, что если ставить глобалке значение по умолчанию, то каждый запуск шаба будет сбивать текущее значение на то самое значение по умолчанию
 
мне всегда казалось, что если ставить глобалке значение по умолчанию, то каждый запуск шаба будет сбивать текущее значение на то самое значение по умолчанию
нет. оно же по умолчанию - только в момент первого запуска самого зеннопостера инициализируется
 
в общем мне раньше очень не хватало иногда двух кубиков - начало лока - и финишь лока, такого городил. да и сейчас - лочить весь кусок в коде - не всегда удобно, когда привык к визуальности кубиков
 
Ну смотри, я прописал по умолчанию 0 и сделал шаб с кубиком с таким содержимым
C#:
Развернуть Свернуть Копировать
project.SendInfoToLog("до:  "+project.GlobalVariables["global", "var1"].Value.ToString(), true);
project.GlobalVariables.SetVariable("global", "var1", new Random().Next(100, 1000));
project.SendInfoToLog("после: "+project.GlobalVariables["global", "var1"].Value.ToString(), true);

И вот лог последовательного запуска этого шаблона в 1 поток
514a95acfb4ec528296a23a9e7d3b8a9.png
 
Ну смотри, я прописал по умолчанию 0 и сделал шаб с кубиком с таким содержимым
C#:
Развернуть Свернуть Копировать
project.SendInfoToLog("до:  "+project.GlobalVariables["global", "var1"].Value.ToString(), true);
project.GlobalVariables.SetVariable("global", "var1", new Random().Next(100, 1000));
project.SendInfoToLog("после: "+project.GlobalVariables["global", "var1"].Value.ToString(), true);

И вот лог последовательного запуска этого шаблона в 1 поток
514a95acfb4ec528296a23a9e7d3b8a9.png
странно, когда запускал когда тестил - не увидел обнуления)) не думал даже что так, ведь по-умолчанию - это если нет значения в пременной, а если оно уже там есть - оно же игнориться должно - то что по умолчанию
 
т.е. выход - вписывать значение не по-умолчанию?) странно всё как-то - глобальная же переменная храниться всю сессию зеннопостера
 
странно, когда запускал когда тестил - не увидел обнуления)) не думал даже что так, ведь по-умолчанию - это если нет значения в пременной, а если оно уже там есть - оно же игнориться должно - то что по умолчанию
не должно)
Так что убирай значение по умолчанию, вообще удали переменную. А на первом локе проверяй, существует ли, через try catch
 
не должно)
Так что убирай значение по умолчанию, вообще удали переменную. А на первом локе проверяй, существует ли, через try catch
посмотри - я поправил первый кубик и текст, надо не ставить никаких значений, а ифе проверять !=null&&!=0

теперь то норм отработает?
 
посмотри - я поправил первый кубик и текст, надо не ставить никаких значений, а ифе проверять !=null&&!=0

теперь то норм отработает?
перезапусти зенно и попробуй. по идее работать не будет, ибо пременной не существует и при обращении будет выбивать ошибку. И будет вечное ожидание
 
перезапусти зенно и попробуй. по идее работать не будет, ибо пременной не существует и при обращении будет выбивать ошибку. И будет вечное ожидание
она же объявлена - почему её не существует? она же просто не проинациализирована и она = null
 
она же объявлена - почему её не существует? она же просто не проинациализирована и она = null
ну пробуй тогда, проверяй. Я глобалки из пм никогда не объявляю. В коде пытаюсь взять значение через трай, и если не получается, знач она не существует, значит задаю значение
 
уххх)) завтра уже докостыляю, чёт мне всё очевидным казалось и в пм всё чётко было, да и в самом зенно проверял - то же всё четкач было. мало тесто сделал
 
  • Спасибо
Реакции: arhip1985
зачем мне что-то лочить в однопотоке?
да, только ты забыл, что тут речь о локе кубиков в многопотоке - и похрен, что поток будет с нуля - если этот переменная локе была изменена уже на 1 - по умолчанию - не поменяет существующую 1 на 0, даже если поток стартует, потому что в ней уже значение записано 1, а не 0
 
как по мне то хрень полная! ТС без обид!!!
что хрень? что значение по-умолчанию всегда перезаписывает существующее значение? зачем тогда во входных настройках поле - по-умолчанию для переменных - только для того - если там ничего нет, а если один из потоков туда что-то записал - то по-умолчанию - не поменяет значение
 
да, только ты забыл, что тут речь о локе кубиков в многопотоке - и похрен, что поток будет с нуля - если этот переменная локе была изменена уже на 1 - по умолчанию - не поменяет существующую 1 на 0, даже если поток стартует, потому что в ней уже значение записано 1, а не 0
поменяет же. Новый поток подрубится и всё поменяет
 
у меня уже бошка не варит( - как значение по-умолчание может поменять - существующее значение существующей переменной? оно же может ставить значение по-умолчанию - если в этой переменной ничего нет на данный момент времени?
 
если первый поток - то 0, на если первый поток поменял глобал на 1, то второй - не запишет ноль, если там уже есть значение, пока первый поток - не закончит свою работу, потому что переменная существует и в ней уже есть значение - она не пустая эта переменная, и значение по-умолчанию - не становится
 
у меня уже бошка не варит( - как значение по-умолчание может поменять - существующее значение существующей переменной? оно же может ставить значение по-умолчанию - если в этой переменной ничего нет на данный момент времени?
значение по умолчанию - значение, которое получит переменная при запуске задания. Значение по умолчанию может быть удобным для локальных переменных, но является абсолютно бессмысленным для глобальных, в некотором смысле даже вредительским
 
я же тебе скидывал скрин - твоего же кода в многопотоке,
ты же видел, что - "до" - не было = 0 в другом потоке
поставь в моём же коде небольшую паузу внутри и вбей число заданий большее, чем число потоков
 
поставь в моём же коде небольшую паузу внутри и вбей число заданий большее, чем число потоков
такая же ситуация в логе, не перезаписывает на ноль, если открыт другой поток, в котором уже есть значение
 

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