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

5

我尝试使用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个回答

6
您的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()返回值为0,向进程0发送信号是不被允许的。


我之前不知道“print”根本不消耗CPU时间!现在我用一些算术代替了打印。非常感谢! - Vasantha Ganesh
1
它确实会使用计算资源,但与通过内核将文本传递到控制台模拟器所花费的时间相比,它所消耗的资源微不足道。然后,控制台模拟器需要将字体渲染到窗口上,并指示窗口管理器向视频驱动程序发送刷新请求,或者进行其他处理。 - spectras
那么当计时器(虚拟)运行时,内核中发生的任何事情都不会被考虑进去,是吗? - Vasantha Ganesh

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接