2010-06-13 3 views
13

Я хочу, чтобы скрипт запускал новый процесс, так что новый процесс продолжает работать после выхода из исходного сценария. Я ожидал, что смогу использовать multiprocessing.Process для запуска нового процесса и установить daemon=True, чтобы основной скрипт мог выйти, пока созданный процесс продолжает работать.Запуск отдельного процесса

Но, похоже, что второй процесс завершается молча при выходе из основного сценария. Это ожидаемое поведение, или я делаю что-то неправильно?

ответ

12

Из документов Python:

Когда процесс завершается, он пытается прекратить все свои процессы демонов ребенка .

Это ожидаемое поведение.

+2

Спасибо, видимо, я не закрыл RTFM достаточно. – JacquesB

8

Если вы на системе UNIX, можно использовать os.fork:

import os 
import time 

pid=os.fork() 
if pid: 
    # parent 
    while True: 
     print("I'm the parent") 
     time.sleep(0.5)  
else: 
    # child 
    while True: 
     print("I'm just a child") 
     time.sleep(0.5) 

Запуск этого создает два процесса. Вы можете убить родителя, не убивая ребенка. Например, при запуске сценария вы увидите что-то вроде:

% script.py 
I'm the parent 
I'm just a child 
I'm the parent 
I'm just a child 
... 

Остановить скрипт с Ctrl-Z:

^Z 
[1]+ Stopped     script.py 

Найти номер идентификатора процесса для родителей. Это будет меньшим из двух чисел идентификатора процесса, так как родитель пришел первый:

% ps axuw | grep script.py 
unutbu 6826 0.1 0.1 33792 6388 pts/24 T 15:09 0:00 python /home/unutbu/pybin/script.py 
unutbu 6827 0.0 0.1 33792 4352 pts/24 T 15:09 0:00 python /home/unutbu/pybin/script.py 
unutbu 6832 0.0 0.0 17472 952 pts/24 S+ 15:09 0:00 grep --color=auto script.py 

убить родительский процесс:

% kill 6826 

Восстановление script.py на передний план:

% fg 
script.py 
Terminated 

Вы увидите, что детский процесс все еще запущен:

% I'm just a child 
I'm just a child 
I'm just a child 
... 

убить ребенка (в новом терминале) с

% kill 6827 
+0

«Вы можете убить родителя, не убив ребенка». Как? –

+0

@MartinThoma: Я добавил подробности о том, как это сделать с терминала выше. Многие операционные системы имеют монитор процесса графического интерфейса, который может сделать это еще проще, но эти детали будут специфичными для ОС/GUI. – unutbu

7

Simply используйте модуль subprocess:

import subprocess 
subprocess.Popen(["sleep", "60"]) 
Смежные вопросы