如何将信号从子进程发送到父进程?

时间:2017-01-19 14:58:43

标签: python

我尝试使用os.kill,但似乎没有效果。

import signal
import os
from time import sleep


def isr(signum, frame):
    print "Hey, I'm the ISR!"

signal.signal(signal.SIGALRM, isr)

pid = os.fork()
if pid == 0:
    def sisr(signum, frame):        
        os.kill(os.getppid(), signal.SIGALRM)

    signal.signal(signal.SIGVTALRM, sisr)
    signal.setitimer(signal.ITIMER_VIRTUAL, 1, 1)

    while True:
        print "2"
else:
    sleep(2)

1 个答案:

答案 0 :(得分:2)

您的sisr处理程序永远不会执行。

signal.setitimer(signal.ITIMER_VIRTUAL, 1, 1)

此行设置虚拟计时器,根据文档,“仅在进程执行时递减间隔计时器 ,并在到期时提供SIGVTALRM”

事实是,你的过程几乎从不执行。打印在您的过程中几乎没有时间,所有工作都由内核将输出传递到控制台应用程序(xterm,konsole,...)和重新绘制屏幕的应用程序完成。与此同时,您的子进程处于睡眠状态,计时器无法运行。

使用真实计时器更改它,它可以工作:)

import signal
import os
from time import sleep


def isr(signum, frame):
    print "Hey, I'm the ISR!"

signal.signal(signal.SIGALRM, isr)

pid = os.fork()
if pid == 0:
    def sisr(signum, frame):        
        print "Child running sisr"
        os.kill(os.getppid(), signal.SIGALRM)

    signal.signal(signal.SIGALRM, sisr)
    signal.setitimer(signal.ITIMER_REAL, 1, 1)

    while True:
        print "2"
        sleep(1)
else:
    sleep(10)
    print "Parent quitting"

输出:

spectras@etherbee:~/temp$ python test.py
2
Child running sisr    
2
Hey, I'm the ISR!
Parent quitting
spectras@etherbee:~/temp$ Child running sisr

Traceback (most recent call last):
  File "test.py", line 22, in <module>
    sleep(1)
  File "test.py", line 15, in sisr
    os.kill(os.getppid(), signal.SIGALRM)
OSError: [Errno 1] Operation not permitted

注意:孩子崩溃第二时运行sisr,因为父母已退出,所以os.getppid()返回{{1禁止向进程0发送信号。