这里我有三个进程,
一个是主进程, 先是 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