Детский процесс должен заканчиваться при получении SIGINT, если только он не игнорирует этот сигнал или имеет свой собственный обработчик. Если вы явно не игнорируете SIGINT в дочернем элементе, возможно, что SIGINT игнорируется в родительском и, следовательно, в дочернем, потому что расположение сигнала наследуется.
Однако, я не смог повторить вашу проблему, на самом деле, я нахожу противоположную проблему: дочерний процесс завершает независимо от его расположения сигнала.
Если сигнал отправлен слишком рано, перед тем, как дочерний процесс проигнорировал SIGINT (в своем методе run()
), он будет завершен. Вот код, который демонстрирует проблему:
import os, time, signal
from multiprocessing import Process
class P(Process):
def run(self):
signal.signal(signal.SIGINT, signal.SIG_IGN)
return super(P, self).run()
def f():
print 'Child sleeping...'
time.sleep(10)
print 'Child done'
p = P(target=f)
p.start()
print 'Child started with PID', p.pid
print 'Killing child'
os.kill(p.pid, signal.SIGINT)
print 'Joining child'
p.join()
Выход
Child started with PID 1515
Killing child
Joining child
Traceback (most recent call last):
File "p1.py", line 15, in
p.start()
File "/usr/lib64/python2.7/multiprocessing/process.py", line 130, in start
self._popen = Popen(self)
File "/usr/lib64/python2.7/multiprocessing/forking.py", line 126, in __init__
code = process_obj._bootstrap()
File "/usr/lib64/python2.7/multiprocessing/process.py", line 242, in _bootstrap
from . import util
KeyboardInterrupt
Добавление небольшую задержку с time.sleep(0.1)
в родителю непосредственно перед отправкой сигнала SIGINT ребенку будет решить эту проблему. Это даст ребенку достаточно времени для выполнения метода run()
, в котором SIGINT игнорируется. Теперь сигнал будет игнорироваться ребенком:
Child started with PID 1589
Killing child
Child sleeping...
Joining child
Child done
Альтернативы, которая не требует никаких задержек, ни обычая run()
метод, чтобы установить родительский игнорировать SIGINT, начать ребенок, а затем восстановить оригинальный обработчик SIGINT родителя ,Поскольку диспозиция сигнал передается по наследству, ребенок будет игнорировать SIGINT с момента его начала:
import os, time, signal
from multiprocessing import Process
def f():
print 'Child sleeping...'
time.sleep(10)
print 'Child done'
p = Process(target=f)
old_sigint = signal.signal(signal.SIGINT, signal.SIG_IGN)
p.start()
signal.signal(signal.SIGINT, old_sigint) # restore parent's handler
print 'Child started with PID', p.pid
print 'Killing child'
os.kill(p.pid, signal.SIGINT)
print 'Joining child'
p.join()
Выход
Child started with PID 1660
Killing child
Joining child
Child sleeping...
Child done
Можете ли вы вставить пример кода? Я попытался сделать это наивно, но он работает так, как ожидалось: https://bpaste.net/show/f2c5fc34b8b6 –
Извините друг i founf сейчас: http://stackoverflow.com/questions/13341870/signals-and-interrupts-a- сравнение – dsgdfg
@ArminRigo большое спасибо, сон до и после отправки сигнала решает проблему, кажется, что это делается очень быстро, можете ли вы отправить его как ответ, чтобы я мог его принять. – Pierre