Как завершать потоки по таймеру?

Moved Поддержка
  • У меня есть шаблон, который работает в многопотоке.
    Мне крайне необходимо поставить таймер выполнения каждого потока, после истечения которого каждый поток завершается (но не весь шаблон).
    К примеру, на выполнение потока отводится ровно 300 секунд. Если поток не выполнил работу за это время, он должен сразу завершиться, после чего стартануть заново.

    Посоветуйте, как лучше всего это сделать и как вообще можно было бы?
    Допустим я оборачиваю работу всего шаблона в Thread() функцию и распараллеливаю ее на 2 потока: первый сверяет таймер каждую 1 секунду, а второй выполняет основную работу скрипта. В результате BAS падает.

    1. Почему BAS падает?
    2. Даже если не будет падать, то как завершать работу самого Thread()? Если таймер истекает и вызвать fail() завершение в TimerCheck(), то завершится поток THREAD_IDNEX == 0, а нужно завершение и 0-го, и 1-го потоков. Вариант завершение всего скрипта не подходит, так как после истечения таймера потоки должны начать заново выполняться.
    3. Есть другой более красивый метод реализации данной задачи? :)

    0_1560358760361_test_mobile_timer.xml

    0_1560358768854_timer_1.png

    0_1560358775744_timer_2.png

    0_1560358811333_timer_3.png

  • @agility said in Как завершать потоки по таймеру?:

    У меня есть шаблон, который работает в многопотоке.
    Мне крайне необходимо поставить таймер выполнения каждого потока, после истечения которого каждый поток завершается (но не весь шаблон).
    К примеру, на выполнение потока отводится ровно 300 секунд. Если поток не выполнил работу за это время, он должен сразу завершиться, после чего стартануть заново.

    Посоветуйте, как лучше всего это сделать и как вообще можно было бы?
    Допустим я оборачиваю работу всего шаблона в Thread() функцию и распараллеливаю ее на 2 потока: первый сверяет таймер каждую 1 секунду, а второй выполняет основную работу скрипта. В результате BAS падает.

    1. Почему BAS падает?
    2. Даже если не будет падать, то как завершать работу самого Thread()? Если таймер истекает и вызвать fail() завершение в TimerCheck(), то завершится поток THREAD_IDNEX == 0, а нужно завершение и 0-го, и 1-го потоков. Вариант завершение всего скрипта не подходит, так как после истечения таймера потоки должны начать заново выполняться.
    3. Есть другой более красивый метод реализации данной задачи? :)

    Нет нулевого потока, нумерация потоков начинается с 0. BAS падает из за бесконечного цикла:
    0_1560359854659_120a3855-11f9-4122-b1ed-a3df7b931726-изображение.png

    Действие "Вызов функции в несколько потоков" завершается мгновенно, потому что оба условия игнорируются:
    0_1560359881543_bdbb557d-b840-46da-b971-a9d627eadd4c-изображение.png

    Так как само действие вызывает потоки №2 и №3


    Реализовать вашу задачу можно через действие "Прервать Скрипт" с опцией "Завершить скрипт мгновенно" в действии "Вызов функции в несколько потоков".

    Так как это действие завершит не весь скрипт, а только действие "Вызов функции в несколько потоков".
    0_1560360472054_c0811ee2-8147-426a-aedd-ee085f384ada-изображение.png

    0_1560360496526_1a007fac-ce7d-4c07-893f-1eba00768150-изображение.png

    Вот тестовый скрипт

  • @fox Спасибо, почти работает. На многопотоке не работает, причем без таймера - при работе с браузером при потоках {{treads}} >= 2 и выполнений {{executions}} >= 2 БАС смешивает потоки и падает.

    Упрощенный вариант без таймера:
    0_1560423456980_test_podpotoki.xml

    В логах видно, что почему-то на 2-ом повторении поток №3 смешивается в поток №4 (при этом браузеры открывает версно №3 и №4).
    Что не так сделано в логике скрипта? Функцию в многопотоке ThreadStart() из Main() нельзя убирать, так как будет потом будет добавлена функция таймера и кол-во потоков 1 изменено на 2.

    0_1560423474559_podpotoki_1.png

    0_1560423482607_podpotoki_2.png

    0_1560423496977_podpotoki_3.png

  • Я думаю первоначальную задачу можно сделать и без завершения потока по таймауту.

    А вообще зачем такой танец с бубном. Делаешь вначале потока дейтсвие дата сейчас и затем во время работы потока повторяешь это действие и сравниваешь разницу во времени. Если время больше - завершить поток.

  • @FastSpace
    Случайно наткнулся на тему со своим похожим вопросом, по поводу таймера)
    По вашему методу получил разницу во времени, далее..
    Вопрос в том, как мне подтянуть данные (число) которого указываю в ресурсах при запуске скрипта, чтобы после истечения времени останавливало поток?

    Помогите разобраться, Спасибо!

  • @Fox said in Как завершать потоки по таймеру?:

    Так как это действие завершит не весь скрипт, а только действие "Вызов функции в несколько потоков".

    Но ведь этот способ прерывает и рабочие потоки. Верно? Есть ли способ прерывать только те потоки которые действительно достигли лимита по времени? Аля watchdog для каждого потока.

    @FastSpace said in Как завершать потоки по таймеру?:

    А вообще зачем такой танец с бубном. Делаешь вначале потока дейтсвие дата сейчас и затем во время работы потока повторяешь это действие и сравниваешь разницу во времени. Если время больше - завершить поток.

    А если встанет поток как раз перед действием которое должно было бы сверить время но до него так и не дошло.

  • "выполнить код" в начале потока:

    THREAD_TIMEOUT = new Date().getTime() + 10000; // 10sec
    DONT_CREATE_MORE = false;
    //
    if (typeof _GetIsRecord == "undefined")
        _GetIsRecord = ScriptWorker.GetIsRecord;
    ScriptWorker.GetIsRecord = function() {
        if (new Date().getTime() > THREAD_TIMEOUT) {
            fail("TimeOut", DONT_CREATE_MORE);
        }
        return _GetIsRecord();
    }
    

    код выше позволяет не писать проверку таймаута перед/после каждого действия.
    и кстати, не позволяйте вашим действиям зависать.

  • @Int64 said in Как завершать потоки по таймеру?:

    код выше позволяет не писать проверку таймаута перед/после каждого действия.
    и кстати, не позволяйте вашим действиям зависать.

    Благодарю! Жаль, но не могу в репу + накинуть(