Як чекати, коли програма запущена в іншій оболонці


20

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


Єдиний інший метод, який я можу уявити, - це створити файл із cronjob, а потім використати inotifywait у цьому процесі, коли файли видалені, ваш 2-й процес (запущений inotifywait) може запуститися.
slm

Я думаю, ви могли б зробити щось у цьому напрямку, використовуючи ipcтакож міжпроцесорний зв’язок. man ipc.
slm

Хоча ви не переглядаєте службу для її перезапуску, Бог, Моніт чи один з інших pkgs, згаданих у цьому запитанні, теж зробив би цю роботу: unix.stackexchange.com/questions/75785/…
slm

@slm можна ініціювати, щоб використовуватись у будь-якій файловій системі, наприклад, зачекати на 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 . Використовуйте команду batch для складання завдань.

Наприклад, ви можете щодня складати всі свої завдання. Пакет може бути налаштований, щоб дозволити деякий паралелізм, щоб заблокована робота не зупиняла весь стек (Це залежить від операційної системи).

ЗРІД №2

Створіть фіфо в домашньому каталозі:

$ mkfifo ~/tata

наприкінці вашої роботи:

echo "it's done" > ~/tata

на початку іншої роботи (того, хто чекає):

cat ~/tata 

Це не опитування, це старе добре блокування IO.

ЗРІД №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 вашого процесу кронів.


4

Немає можливості для процесу, щоб чекати, коли інший процес закінчиться, крім батьків, які чекають, коли один із його дочірніх процесів завершиться. Якщо можете, запустіть програму за допомогою сценарію:

do_large_amount_of_work
start_interactive_program

Якщо ви не можете цього зробити, наприклад, перш ніж ви хочете розпочати велику кількість роботи з роботи з cron, але інтерактивну програму з контексту вашої сесії, тоді зробіть це

do_large_amount_of_work
notify_completion

Існує кілька способів реалізації notify_completion. У деяких середовищах робочого столу передбачений механізм сповіщення ( може бути корисним відкрити вікно на віддаленому дисплеї X (чому "Не вдається відкрити дисплей")? Ви також можете зробити одне, використовуючи сповіщення про зміну файлів. В Linux засіб сповіщення про зміну файлів ініціюється .

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зазвичай порожньо, якщо ви не побачите, що вам потрібно запустити подальше завдання.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.