多进程 socket exit的问题

本文探讨了一个Python Socket Server中遇到的问题,即使用Ctrl+C无法正常关闭多进程监听程序。通过深入分析异常处理流程,特别是KeyboardInterrupt与SystemExit之间的相互作用,找到了合理的解决方案。

写了一个 forking 多进程socket 的 server 原型

运行系统是FB。 却发现 ctrl + c 无法关闭这个正在监听的程序。

import socket,traceback,os,sys import signal,time def reap(): while 1: try: result = os.waitpid(-1,os.WNOHANG) if not result[0]: break except: break print "reap process %d" % result[0] def sigint_handler(signum,frame): print 'eeexxeexx' #s.close() print 'close' sys.exit() signal.signal(signal.SIGINT,sigint_handler) host = 'localhost' port = 9009 s = socket.socket(socket.AF_INET,socket.SOCK_STREAM) s.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1) s.bind((host,port)) s.listen(1) print "parent at %d" % os.getpid() while 1: try: clientsock,clientaddr = s.accept() except: #print sys.exc_info()[0] traceback.print_exc() time.sleep(2) print os.getpid() continue #s.close() #sys.exit() reap() pid = os.fork() if pid: clientsock.close() continue else: s.close() try: print "child is %d" % 2 while 1: data = clientsock.recv(4096) if not len(data): break clientsock.sendall(data) time.sleep(10) print "%s" % data except: raise sys.exit(0)

看代码

首先。 我自定义捕获ctrl + c 信号

def sigint_handler(signum,frame): print 'eeexxeexx' #s.close() print 'close' sys.exit() signal.signal(signal.SIGINT,sigint_handler)

在捕获信号里面 使用了 sys.exit()退出 程序。

再看下监听部分:

while 1: try: clientsock,clientaddr = s.accept() except: #print sys.exc_info()[0] traceback.print_exc() #time.sleep(2) print os.getpid() continue #s.close() #sys.exit()

不断在监听,是否有客户端连接,如果产生异常就 continue 继续回到上头去监听。

问题:为啥就ctrl + c 就退出不了呢。加了调试参数(就是带注释的那些)研究了半天。终于明白了

ctrl +c 以后抛出了 KeyboardInterrupt 异常,而我在捕获信号函数里面,又使用了 sys.exit()方法,这个方法会抛出 SystemExit

这个看手册才知道: This is implemented by raising the SystemExit exception

异常而覆盖了前面的 KeyboardInterrupt。 就这样代码是以 SystemExit异常而跑到了 except: 异常处理区。 而异常处理区里我使用了 continue 让程序回到监听状态。就这样导致了 sys.exit() 无效了等于。 可以做个小实验证明这个答案是否正确。 看上面代码,我在异常处理区加入了 time.sleep(2) 让程序在异常处理区卡住运行两秒。

然后再运行这个程序。结果是。我连续按两下 ctrl + c ,就可以正常退出了 程序。 这个很好理解了。 因为当我第一次按下 ctrl + c 的时候。程序跑到了 异常处理区而且 time.sleep(2) 两秒。 就在这会我继续 来多一次 ctrl + c 等于又多发出一个异常。但这会的程序是运行在异常处理区,而异常处理区我没有再处理这里发生的异常了。所以这会代码就运行到这里

def sigint_handler(signum,frame): print 'eeexxeexx' #s.close() print 'close' sys.exit()

sys.exit() 发出了退出的异常。没人接收这个异常的话,就直接退出了程序。

解决办法就是。不要 捕获 KeyboardInterrupt 和 SystemExit 。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值