Как поднять KeyboardInterrupt до скриптов Python после прерывания GNU Parallel?

Я использую GNU Parallel для запуска скрипта Python для списка различных аргументов. Внутри скрипта Python я пишу данные в файл (на самом деле имя файла является аргументом скрипта). Сценарий Python записывает данные в файл после обработки N попыток, где N — еще один аргумент. Следовательно, данные не записываются до тех пор, пока не будут завершены все испытания. Но время на прохождение суда может варьироваться в зависимости от количества тестовых аргументов. По этой причине, если сценарий занимает слишком много времени для определенного набора аргументов, сценарий позволяет мне вызвать ошибку KeyboardInterrupt (Ctrl+C) и записать полученные данные перед завершением.

Однако при использовании GNU Parallel использование Ctrl+C уничтожит параллельную команду и полностью остановит задания Python, поэтому данные пока не записываются.

Можно ли вызвать KeyboardInterrupt в этих сценариях Python, чтобы они закончили обработку ошибки до того, как параллельный режим будет уничтожен? В идеале это должно выглядеть примерно так: 1. Выполнить parallel python script.py ::: args, 2. Через некоторое время отменить с помощью Ctrl+C, 3. Parallel сообщает скриптам Python, что нужно увидеть прерывание клавиатуры (или любую другую ошибку, это не имеет значения) и Parallel приостанавливает ждать завершения обработки заданий Python, 4. Параллельное завершение, 5. У меня есть файлы с данными, полученными за это время.

Примечание. Мне нужен ответ, который не просит переписать метод записи данных скрипта Python.


person Zachary    schedule 14.09.2020    source источник


Ответы (1)


Я полагаю, вы ищете --termseq. myprog.pl:

#!/usr/bin/perl

$SIG{'TERM'} = sub { print "TERM received. Flush files.\n"; sleep(1); };

sleep(100);

Теперь запустите:

parallel --termseq TERM,2000,KILL,20 -u ./myprog.pl ::: 1 2 3

Когда GNU Parallel получает ctrl-c, он отправляет SIGTERM дочернему элементу, ждет 2000 мс и, если дочерний элемент еще жив, убивает его.

Подождите несколько секунд и нажмите ctrl-c

Если вы абсолютно уверены, что программа Python завершит работу после получения SIGTERM, вы можете удалить ,KILL,20. Это просто запасной вариант, если программа Python по какой-то причине зависла.

person Ole Tange    schedule 16.09.2020
comment
Потрясающий! --termseq было именно то, что мне было нужно. Однако я обнаружил, что SIGTERM не работает. Но после просмотра других сигналов завершения, похоже, что использование SIGINT сделало именно то, что я хотел. Благодарю вас! - person Zachary; 16.09.2020