Сделал заготовку под многопоточные шаблоны (Есть глюки!)

Регистрация
26.05.2020
Сообщения
495
Благодарностей
172
Баллы
43
Покурив кучку тем на форуме по поводу многопотока, накропал свою болванку под будущие проекты.
Использую глобальную переменную count в окружении test...

В одном потоке отрабатывает все красиво...

71600


Запускаю шаблон в 3 потока (у меня создано 3 юзера в списке соответствующего шаблона)

71603


буквально через несколько циклов в логах вижу бардак...

71601


Сам шаблон прикрепляю, может, знатоки помогут найти бяку? Вопрос возник с того, что параллельно выполняются 2 одинаковых задачи на рабочем проекте...
PS: Zenno 7.3.0.0
 

Вложения

Phoenix78

Client
Read only
Регистрация
06.11.2018
Сообщения
11 790
Благодарностей
5 718
Баллы
113
а где лок у тебя ?
как ты собираешься работать в многопотоке без локирования ресурсов ?
в переменных точно никакого лока нет, вроде бы при работе со списком есть лок, но сколько не пытался обычные кубики использовать, ничего хорошего это не приносило. Поэтому кури тему с локированием ресурсов и будет у тебя нормальный многопоток.
 
  • Спасибо
Реакции: DevOps
Регистрация
26.05.2020
Сообщения
495
Благодарностей
172
Баллы
43
а где лок у тебя ?
как ты собираешься работать в многопотоке без локирования ресурсов ?
в переменных точно никакого лока нет, вроде бы при работе со списком есть лок, но сколько не пытался обычные кубики использовать, ничего хорошего это не приносило. Поэтому кури тему с локированием ресурсов и будет у тебя нормальный многопоток.
А что переменные разве тоже требуют локировки? o_O
 

Phoenix78

Client
Read only
Регистрация
06.11.2018
Сообщения
11 790
Благодарностей
5 718
Баллы
113

volody00

Client
Регистрация
06.09.2016
Сообщения
917
Благодарностей
950
Баллы
93
держи супер костыльное решение с локом на кубиках. Но как по мне в логике что-то выстроено не так (в чем твоя задача я так до конца и не врубился), это уж я по приколу больше накидал, интересно было решить задачку. Соответственно, в данном случае по сути начиная от 1-го и до последнего кубика стоит лок, а значит даже при запуске в многопотоке конкретно этот участок будет выполняться в однопоток.
 

Вложения

  • Спасибо
Реакции: Андрейка2020
Регистрация
26.05.2020
Сообщения
495
Благодарностей
172
Баллы
43
если глобалки, то да.
Не подскажешь, как это сделать или может ссылочкой поделишься на рабочее решение?
А то я одно нарыл что-то, но код не работает...
держи супер костыльное решение с локом на кубиках.
Ценкью, посмотрю, что к чему!..
 

volody00

Client
Регистрация
06.09.2016
Сообщения
917
Благодарностей
950
Баллы
93
Не подскажешь, как это сделать или может ссылочкой поделишься на рабочее решение?
А то я одно нарыл что-то, но код не работает...

Ценкью, посмотрю, что к чему!..
ты никак не сможешь совместить лок, написанный на c# с кубиками. Посмотрел мой шаб? Распиши подробно задачу, ребята подскажут тебе оптимальное решение. почему так важно, чтобы конкретный поток брал конкретно свою строку? Если ты запускаешь 20 потоков, то там один поток может опережать другой. сохранять очередность в большинстве не нужно (может и невозможно)
 
Регистрация
26.05.2020
Сообщения
495
Благодарностей
172
Баллы
43
ты никак не сможешь совместить лок, написанный на c# с кубиками.
если не разместить все кубики внутрь лок, кака я понял...
Посмотрел мой шаб?
Нет еще, курю форум ))) Гляну обязательно!
почему так важно, чтобы конкретный поток брал конкретно свою строку?
Да в принципе неважно, я просто для наглядности в шаб внес эти данные... Но!..
Если ты запускаешь 20 потоков, то там один поток может опережать другой
И тут рождается еще одна хотелка (скорее, для начала вопрос) для реализации: возможно ли как-то ограничивать количество одновременно работающих потоков? В моем случае, это количество строк из списка юзеров...

Задача такая: имеем список юзеров с логинами и паролями от кучки сайтов, хочется, чтоб они работали одновременно. в моем случае их 3, но вполне может стать и 4 и 5 в дальнейшем. Прикол в том, что на моем демо-шабе прикрепленном не наблюдается двойной загрузки одного юзера в 2 потоках одновременно (при старте актуально), а на боевом шабе такое практикуется... И я так полагаю, что возможно будущем еще какие грабли всплывут...
 
Регистрация
26.05.2020
Сообщения
495
Благодарностей
172
Баллы
43
Посмотрел мой шаб?
Посмотрел... Не понял, зачем там переменная с датой и второй вопрос, через переменную flag ты по сути в очередь потоки ставишь, что не есть гуд. Вся суть многопоточности потеряна.
 

volody00

Client
Регистрация
06.09.2016
Сообщения
917
Благодарностей
950
Баллы
93
Посмотрел... Не понял, зачем там переменная с датой и второй вопрос, через переменную flag ты по сути в очередь потоки ставишь, что не есть гуд. Вся суть многопоточности потеряна.
В этом и есть суть лока. Лок- эта область, куда другие потоки не могут попасть какое-то время. Ты его ставишь в то место, где потоки потенциально могут мешать друг другу. Да, суть потеряна, но этот участок и не должен распространяться на весь шаблон.

Переменная с датой так-то не нужна, я не доделал. Можешь убрать
 

volody00

Client
Регистрация
06.09.2016
Сообщения
917
Благодарностей
950
Баллы
93
Ты можешь сделать табличку со статусами занят и свободен. При отборе у логинов и паролей обязательно должен быть статус свободен, а когда поток взял то даёт статус занят. Это для многопотока, чтобы 1 акк не брали
 

Bablozavr

Client
Регистрация
26.01.2018
Сообщения
310
Благодарностей
164
Баллы
43
Я же объяснял тебе, в другой теме :-)
Сохраняй счетчик в список, к списку привяжи файл (куда будет сохранятся число), вот тебе на c# решение:
C#:
var sourceList = project.Lists["Счетчик"];

// текущий поток применяет лок к списку (и файлу)
lock(SyncObjects.ListSyncer) {
    project.Variables["Counter"].Value = sourceList.First(); // в переменную Counter сохранили число из списка "Счетчик"

    int counter = Convert.ToInt32(sourceList.First()) + 1; // увеличили текущее значение счетчика на 1

    sourceList.Clear(); // очистили список
    sourceList.Add(counter.ToString()); // записали новое значение счетчика, которое возьмет следующий поток
}
// операции со списком завершились, лок снят, к списку получает доступ следующий поток
// пока стоит лок, остальные потоки ждут своей очереди
Лок будет работать при работе со списком и просто на кубиках, c# не обязателен, если так будет проще для тебя :-)
 
Последнее редактирование:
Регистрация
26.05.2020
Сообщения
495
Благодарностей
172
Баллы
43
Сохраняй счетчик в список, к списку привяжи файл (куда будет сохранятся число)
башка уже не варит совсем :D
А есть вариант без списка на Сишарпе? Просто залочить переменную {-GlobalVariable.test.count-} на момент обращения к ней... И чтоб при увеличении +1 задать максимальное число счетчика можно было?

71625


Мне вот получается вот эту всю конструкцию (выделено рамкой) нужно в лок засунуть, правильно я понимаю? Или достаточно только Перед первым кубиком код лока вставить?
Аааа, бляяяя... Мой башка на взрыв пашёль!..
 
Регистрация
26.05.2020
Сообщения
495
Благодарностей
172
Баллы
43
Ах я криворукий рукожоп! :D

Перерисовал кубики более логично

71626


Зато теперь я понял, чего не хватает в зенке - в контекстном меню функции "lock(SyncObjects."
Было бы прям удобно выделил группу кубиков нужных и добавил ее в отдельный "блокиратор". или как там правильно это называется...

71627
 
Последнее редактирование:
Регистрация
05.06.2019
Сообщения
570
Благодарностей
454
Баллы
63
Ах я криворукий рукожоп! :D

Перерисовал кубики более логично

Посмотреть вложение 71626

Зато теперь я понял, чего не хватает в зенке - в контекстном меню функции "lock(SyncObjects."
Было бы прям удобно выделил группу кубиков нужных и добавил ее в отдельный "блокиратор". или как там правильно это называется...

Посмотреть вложение 71627
Примерно так
C#:
string temp = project.Variables["partner_balance_count_user"].Value;
string temp2 = project.Variables["count_user"].Value;

lock(CommonCode.SyncObject) // обязательно должен быть активен общий код
{
    if (string.IsNullOrEmpty(temp))
    {
        project.Variables["count_user"].Value = "1";
        return "ok";
    }
    else if (int.TryParse(temp, out int partner_balance_count_user))
    {
        if (partner_balance_count_user >= 3)
        {
            project.Variables["count_user"].Value = "1";
            return "ok";
        }
        
        if (int.TryParse(temp2, out int count_user))
        {
            project.Variables["count_user"].Value = (count_user + 1).ToString();
        }
    }
}
 
  • Спасибо
Реакции: Андрейка2020
Регистрация
26.05.2020
Сообщения
495
Благодарностей
172
Баллы
43
Это глобальная переменная {-GlobalVariable.partner_balance.count_user-}, там вроде как-то иначе они задаются?
обязательно должен быть активен общий код
Это как проверить?
project.Variables["count_user"].Value = "1";
Это она же {-GlobalVariable.partner_balance.count_user-} - просто зенка кубики показывает так, как видим на скрине...
 
Регистрация
05.06.2019
Сообщения
570
Благодарностей
454
Баллы
63
71664


Глобальные переменные в проекте используется для передачи данных между проектами?
 
Последнее редактирование:

Bablozavr

Client
Регистрация
26.01.2018
Сообщения
310
Благодарностей
164
Баллы
43
Регистрация
26.05.2020
Сообщения
495
Благодарностей
172
Баллы
43
Благодарю Маломальский за оказанную в скайпе индивидуальную помощь! :bf:
Вопрос успешно решен!

C#:
int count_user = 0;

lock(CommonCode.SyncObject) // обязательно должен быть активен общий код
{
    count_user = CommonCode.count_user;

    if (count_user >= 2)
        {
            CommonCode.count_user = 0;
            project.Variables["num_user"].Value = "0";
        }
        else
    {
        int temp = CommonCode.count_user += 1; // равноценно: 1) переменная = переменная + 1; 2) или temp++;
        // project.SendInfoToLog(CommonCode.count_user.ToString());
        project.Variables["num_user"].Value = temp.ToString();
    }

}
 

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