父子进程 signal 出现 Interrupted system call 问题

这里我有三个进程,

一个是主进程, 先是 fork 一个子进程 ppid

然后 ppid 又 fork一个子进程 pid

目的是让 ppid 来启动 pid, 并负责 pid 的正常运行(例如 pid 如果退出了,可以让 ppid 来重新启动它)

但是我想要在主进程中利用一个信号来结束这个进程(pid), 然后ppid 得到 waitpid(pid, 0) 的返回值,最终整个分支进程全部退出.

代码如下:

import os
import time
import signal
def my_fork():
    ppid = os.fork()
    if ppid == 0:
        pid = os.fork()
        if pid == 0:
            global n
            n = 1
            def handler(signum, frame):
                print "Catch the signal %s" % signum
                global n
                n = 0
            signal.signal(signal.SIGUSR1, handler)
            print "The p child %s" % os.getpid()
            # run the logger progream
            while 1:
                if n:
                    print "sleeping..."
                else:
                    print "EXIT..................."
                    break
                time.sleep(1)
            os._exit(n)
        def handler(signum, frame):
            os.kill( pid, signum)
        signal.signal(signal.SIGUSR1, handler)
        print "The pp child %s" % os.getpid()
        status = 1
        try:
            status = os.waitpid(pid, 0)[1]        # 代码[1]
        except OSError,e:
            if e.errno == 4:        
                print "###########%s %s"%(pid, id(pid))
                print str(e)
        if status == 0:
            print "The pid %s exit normally" % pid
        os._exit(status)
    else:
        time.sleep(3)
        os.kill(ppid, signal.SIGUSR1)
        os.waitpid(ppid, 0)

if __name__ == "__main__":
    my_fork()

遇到一问题, 如果代码[1]处不加 try except处理,则会得到一个 OSError 

The p child 6555
sleeping...
The pp child 6554
sleeping...
sleeping...
Traceback (most recent call last):
  File "fork1.py", line 45, in <module>
    my_fork()
  File "fork1.py", line 35, in my_fork
    status = os.waitpid(pid, 0)[1]
OSError: [Errno 4] Interrupted system call
Catch the signal 10
EXIT...................

google了半天也没有解决问题,最终还是用 try except 来处理的. 因为发现别人也是这么处理的...

http://marc.info/?l=zodb-checkins&m=106930249605396&w=1

+                        raise KidDiedOnMeError
+                    except OSError, num:
+                        if num == 4:
+                            # This is likely an interrupted system call
+                            # inside os.waitpid caused by a signal.
+                            # Though we have to catch it, we don't really
+                            # care about it and we just pass.
+                            pass

原文地址:https://www.cnblogs.com/sunblackshine/p/1950282.html