Как мне ждать, когда программа запущена в другой оболочке

20

У меня есть программа, выполняющая большой объем работы (занимает около 4-5 часов), которая запускается cron, когда становятся доступными все данные, с которыми она работает. Иногда, когда я жду, пока он закончится, я хотел бы иметь возможность запустить другую (интерактивную) программу, когда она закончится. ожидание вызова выглядит многообещающим, но будет ждать только детей.

hildred
источник
Единственный другой метод, который я могу придумать, - это создать файл из cronjob, а затем использовать inotifywait для этого процесса, когда файлы будут удалены, ваш 2-й процесс (запущенный inotifywait) может запуститься.
SLM
Я думаю, что вы могли бы что-то сделать в этом направлении, используя ipcтакже межпроцессное взаимодействие. man ipc,
SLM
Хотя вы не смотрите на службу , чтобы перезапустить его, Боже, монит, или один из других pkgs , упомянутых в этом Q & A будет делать эту работу тоже: unix.stackexchange.com/questions/75785/...
слм
@slm можно использовать inotify в любой файловой системе, например, ждать закрытия close_write в / proc / _pid_ / fd / 1?
Hildred
Не совсем уверен, но это может быть другой способ сделать это 8-). Был какой-то вопрос, который я помню, где были некоторые новые функциональные возможности ядра, связанные с мониторингом процессов, аналогичные inotifywait (для файлов). Я думал, что эта новая функция предназначена для событий в процессе, но многие вопросы и ответы начинают работать вместе в моей голове 8-). Я думаю, что А был предоставлен мной или Жилем.
SLM

Ответы:

13

Я определенно предпочитаю решение EDIT # 3 (см. Ниже).

если его не в той же оболочке использовать то время как цикл с условием на пс -p возвращает истину. Включите режим сна, чтобы уменьшить нагрузку на процессор.

while ps -p <pid> >/dev/null 2>&1
do
   sleep 10
done 

или если ваш UNIX поддерживает / proc (например, HP-UX все еще не поддерживает).

while [[ -d /proc/<pid> ]]
do 
    sleep 10
done

Если вы хотите тайм-аут

timeout=6  # timeout after 1mn  
while ((timeout > 0)) && ps -p <pid> >/dev/null 2>&1
do
   sleep 10
   ((timeout -= 1))
done 

РЕДАКТИРОВАТЬ # 1

Есть другой способ: не используйте cron . Используйте пакетную команду, чтобы сложить ваши задания.

Например, вы можете ежедневно складывать все свои работы. Пакет может быть настроен для обеспечения некоторого параллелизма, поэтому заблокированное задание не остановит весь стек (это зависит от операционной системы).

РЕДАКТИРОВАТЬ № 2

Создайте fifo в вашем домашнем каталоге:

$ mkfifo ~/tata

в конце вашей работы:

echo "it's done" > ~/tata

в начале другой работы (тот, кто ждет):

cat ~/tata 

Это не опрос, это старая хорошая блокировка ввода-вывода.

РЕДАКТИРОВАТЬ № 3

Используя сигналы:

В начале сценария (ов) кто (а) ждет:

echo $$ >>~/WeAreStopped
kill -STOP $$

в конце вашей долгой работы:

if [[ -f ~/WeAreStopped ]] ; then
    xargs kill -CONT < ~/WeAreStopped
    rm ~/WeAreStopped
fi
Эммануэль
источник
Опрос, гадость! Прекрасное решение: потратить время процессора или мое время на настройку сна. Должен быть лучший ответ.
hildred
:) Опрос хорош для вас, опрос без сохранения состояния, опрос надежен.
Эммануил
Опрос идет медленно, тратит впустую процессорное время.
Hildred
При времени исполнения 0,01 с 1440 пс, выполненные в течение 4 часов, потребовали бы 14,4 с. Намного меньше, чем планировщик, управляющий зависимостями рабочих мест: D
Эммануэль
Я думаю, что это, вероятно, лучший вариант: stackoverflow.com/questions/1058047/… , хотя он и хакерский.
SLM
5

Вы можете изменить свою работу cron, чтобы использовать какой-либо флаг.

Вместо того

2  2 * * *           /path/my_binary

Вы можете использовать

2  2 * * *           touch /tmp/i_m_running; /path/my_binary; rm /tmp/i_m_running

И просто контролировать этот файл в сценарии или даже вручную. Если он существует, значит, ваша программа работает; в противном случае не стесняйтесь делать все, что вы хотите.

Пример скрипта:

while [[ -f /tmp/i_m_running ]] ; do
   sleep 10 ;
done
launch_whatever_you_want

Если вам не нравится использовать sleep, вы можете изменить скрипт и запускать его через cron один раз в X минут.

В этом случае пример скрипта будет:

[[ -f /tmp/i_m_running ]] && { echo "Too early" ; exit ; }
launch_whatever_you_want

Этот способ немного проще, так как вам не нужно находить PID вашего процесса cron.

порыв
источник
4

У процесса нет возможности ожидать завершения другого процесса, за исключением того, что родительский процесс ожидает завершения одного из своих дочерних процессов. Если вы можете, запустите программу через скрипт:

do_large_amount_of_work
start_interactive_program

Если вы не можете сделать это, например, перед тем, как хотите начать большой объем работы с задания cron, но с интерактивной программой из контекста сеанса, сделайте это

do_large_amount_of_work
notify_completion

Есть несколько способов реализации notify_completion. В некоторых средах рабочего стола предусмотрен механизм уведомлений ( может быть полезно открыть окно на удаленном дисплее X (почему «Не удается открыть дисплей»)? ). Вы также можете сделать один, используя уведомления об изменении файла. В Linux средство уведомления об изменении файла - inotify .

do_large_amount_of_work
echo $? >/path/to/finished.stamp

Реагировать на создание /path/to/finished.stamp:

inotifywait -e close_write -q /path/to/finished.stamp
start_interactive_program

Если вы не можете изменить способ do_large_amount_of_workвызова, но знаете, какой файл он изменяет последним, вы можете использовать тот же механизм, чтобы реагировать, когда этот файл закрыт. Вы также можете реагировать на другие события, такие как переименование файла ( inotifywaitсписок возможностей см. В руководстве).

Жиль "ТАК - перестать быть злым
источник
0

Пусть сценарий, запускаемый cronjob, вызывает пустой сценарий оболочки, в который вы можете вставить последующие задачи, если они вам нужны.

Это очень похоже на подход Жиля.

cronjob-task.sh содержит:

# do_large_amount_of_work

./post-execute.sh

где post-execute.shобычно пусто, если только вы не видите, что вам нужно запустить последующую задачу.

Даниэль Ф
источник