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

Сразу предыдущий?

Вы имеете в виду следующее, правильно?

previous = None
for item in someList:
    if item == target: break
    previous = item
# previous is the item before the target

, Если Вы хотите n предыдущие объекты, можно сделать это со своего рода круговой очередью размера n.

queue = []
for item in someList:
    if item == target: break
    queue .append( item )
    if len(queue ) > n: queue .pop(0)
if len(queue ) < n: previous = None
previous = previous[0]
# previous is *n* before the target
14
задан John Zwinck 2 October 2009 в 13:03
поделиться

3 ответа

Поскольку они не были предметом системного вызова wait (2) .

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

Когда вы его запустите. из оболочки, ваша оболочка перехватывает SIGCHLD и в любом случае выполняет различные операции ожидания, поэтому ничего не остается неработающим надолго.

Но cron не в состоянии ожидания, он спит, поэтому несуществующий дочерний элемент может оставаться на некоторое время пока cron не проснется.


Обновление: Ответ на комментарий ... Хм. Мне удалось продублировать проблему:

 PPID   PID  PGID  SESS COMMAND
    1  3562  3562  3562 cron
 3562  1629  3562  3562  \_ cron
 1629  1636  1636  1636      \_ sh <defunct>
    1  1639  1636  1636 sleep

Итак, что произошло, я думаю:

  • cron разветвляется, и дочерний элемент cron запускает оболочку
  • оболочка (1636) запускает sid и pgid 1636 и запускает спящий
  • оболочку , SIGCHLD, отправленный на cron 3562
  • , игнорируется или обрабатывается неправильно
  • оболочка превращает зомби. Обратите внимание, что сон заменен на init, поэтому, когда он выйдет из спящего режима, init получит сигнал и очистится. Я все еще пытаюсь понять, когда зомби пожнут. Вероятно, при отсутствии активных детей cron 1629 выясняет, что он может выйти, в этот момент зомби будет повторно запущен для инициализации и будет пожат. Итак, теперь мы задаемся вопросом об отсутствии SIGCHLD, который cron должен был обработать.
    • Это не обязательно ошибка vixie cron. Как вы можете видеть здесь, libdaemon устанавливает обработчик SIGCHLD во время daemon_fork () , и это могло помешать доставке сигнала при быстром выходе промежуточным звеном 1629

      Я даже не знаю, построен ли vixie cron в моей системе Ubuntu с помощью libdaemon, но, по крайней мере, у меня есть новая теория. :-)

13
ответ дан 1 December 2019 в 12:13
поделиться

Я подозреваю, что cron ожидает завершения всех подпроцессов в сеансе. Смотрите wait (2) относительно отрицательных аргументов pid. Вы можете увидеть SESS с помощью:

ps faxo stat,euid,ruid,tty,tpgid,sess,pgrp,ppid,pid,pcpu,comm

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

STAT  EUID  RUID TT       TPGID  SESS  PGRP  PPID   PID %CPU COMMAND
Ss       0     0 ?           -1  3197  3197     1  3197  0.0 cron
S        0     0 ?           -1  3197  3197  3197 18825  0.0  \_ cron
Zs    1000  1000 ?           -1 18832 18832 18825 18832  0.0      \_ sh <defunct>
S     1000  1000 ?           -1 18832 18832     1 18836  0.0 sleep

Обратите внимание, что sh и sleep находятся в одном SESS.

Используйте команду setsid (1). Вот tester.sh:

#!/bin/bash
setsid sleep 27 # the real script launches a compiled C program in the background

Обратите внимание, что вам не нужны & , setsid помещает его в фоновый режим.

4
ответ дан 1 December 2019 в 12:13
поделиться

Я бы порекомендовал вам решить проблему, просто не создавая двух отдельных процессов: Сделайте это в последней строке launcher.sh :

exec "$@"

Это устранит лишний процесс.

3
ответ дан 1 December 2019 в 12:13
поделиться
Другие вопросы по тегам:

Похожие вопросы: