在另一个线程中分配一个孩子:父母在终止时没有收到SIGCHLD

时间:2016-05-25 07:35:43

标签: python multiprocessing posix

通常,当进程 fork 子进程时,如果该子进程终止,它将收到SIGCHLD信号。但是,如果此 fork 发生在应用程序的主线程之外的线程中,则父级将不会收到任何内容。

我在不同的GNU / Linux机器上用Python测试它。全部都是x86_64

我的问题是:它是Python行为,还是POSIX Standard的定义行为?在这两种情况下,为什么会如此?

以下是重新产生此行为的示例代码。

import signal
import multiprocessing
import threading
import time


def signal_handler(*args):
    print "Signal received"

def child_process():
    time.sleep(100000)

def child_thread():
    p = multiprocessing.Process(target=child_process)
    p.start()
    time.sleep(100000)


signal.signal(signal.SIGCHLD, signal_handler)

p = multiprocessing.Process(target=child_process)
p.start()

t = threading.Thread(target=child_thread)
t.start()

time.sleep(100000)
print "Waked"
time.sleep(100000)

然后,向每个孩子发送SIGKILL。当第一个子节点(在主线程中分叉的子节点)终止时,将调用signal_handler。但当第二个孩子终止时,什么都不会发生。

我还使用os.fork而非multiprocessing.Process测试相同的方案。结果相同。

1 个答案:

答案 0 :(得分:0)

documented python behavior

  

只有主线程可以设置一个新的信号处理程序,而是主要的   线程将是唯一一个接收信号的线程(这是由强制执行的   Python信号模块,即使是底层线程实现   支持向各个线程发送信号)。这意味着   信号不能用作线程间通信的手段。使用   而是锁定。