Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/maven/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python中的信号处理程序中断选择的乐趣_Python_Multithreading_Signals - Fatal编程技术网

Python中的信号处理程序中断选择的乐趣

Python中的信号处理程序中断选择的乐趣,python,multithreading,signals,Python,Multithreading,Signals,我正在做一个编程项目——用Python编写一个基本的P2P文件共享应用程序。我使用两个线程:一个主线程调用select并等待sockets和sys.stdin列表的输入(接收键入的命令),另一个助手线程从队列中取出状态更新消息并打印它们。(这是唯一可以打印任何东西的东西) 我还需要捕获标准SIGINT并处理它以优雅地退出。我有一个退出方法可以做到这一点;键入'quit'作为命令就可以了。因此,在主线程中,我尝试将此方法设置为SIGINT的处理程序。据我所知,进程捕获信号并调用quit方法。助手线

我正在做一个编程项目——用Python编写一个基本的P2P文件共享应用程序。我使用两个线程:一个主线程调用select并等待sockets和sys.stdin列表的输入(接收键入的命令),另一个助手线程从队列中取出状态更新消息并打印它们。(这是唯一可以打印任何东西的东西)

我还需要捕获标准SIGINT并处理它以优雅地退出。我有一个退出方法可以做到这一点;键入'quit'作为命令就可以了。因此,在主线程中,我尝试将此方法设置为SIGINT的处理程序。据我所知,进程捕获信号并调用quit方法。助手线程打印一条消息,确认它正在退出。但随后我从主线程得到以下错误消息:

Traceback (most recent call last):
  File "peer.py", line 226, in <module>
    main()
  File "peer.py", line 223, in main
    p.run()
  File "peer.py", line 160, in run
    readables, writables, exceptions = select(self.sockets, [], [])
select.error: (4, 'Interrupted system call')
回溯(最近一次呼叫最后一次):
文件“peer.py”,第226行,在
main()
文件“peer.py”,第223行,在main中
p、 运行()
文件“peer.py”,第160行,运行中
可读、可写、异常=选择(self.sockets、[]、[])
select.error:(4,“中断的系统调用”)
之后程序仍然会退出。而在没有信号处理程序的情况下,发送SIGINT会给我以下信息:

Traceback (most recent call last):
  File "peer.py", line 225, in <module>
    main()
  File "peer.py", line 222, in main
    p.run()
  File "peer.py", line 159, in run
    readables, writables, exceptions = select(self.sockets, [], [])
KeyboardInterrupt
回溯(最近一次呼叫最后一次):
文件“peer.py”,第225行,在
main()
文件“peer.py”,第222行,在main中
p、 运行()
文件“peer.py”,第159行,运行中
可读、可写、异常=选择(self.sockets、[]、[])
键盘中断

未能终止该计划;我必须停下来杀了它。这是令人困惑的,因为只有当我的自定义方法捕捉到SIGINT时,它才会中断对select的调用。(这只会将一条消息放入打印队列并设置一个“done”变量)有人知道这是如何发生的吗?尝试同时使用信号处理程序和线程是不是一个坏主意?

我不确定是否要使用信号处理程序来捕获这种情况,但我在这里找到了在基于*nix的系统上处理这种情况的方法:

简而言之(如果我理解正确):

在启动任何新线程之前,请派生一个子进程(使用
os.fork
)以完成程序运行,并让父进程监视
键盘中断


当父进程捕捉到键盘中断时,您可以使用
os.kill
终止子进程(现在可能已经启动了其他线程)。这将反过来终止该子进程的所有线程。

是的,昨晚在我停止工作后,我意识到我确实希望它中断。据推测,它被执行信号处理程序所中断。因此,我只是捕获select.error并让它跳到循环的末尾,在那里它会立即退出并继续执行清理代码。

你能发布一段复制此行为的代码吗?是的,昨晚我停止处理它后,我意识到我确实希望它中断。据推测,它被执行信号处理程序所中断。所以我只捕获select.error并让它跳到循环的末尾,在那里它立即退出并继续执行清理代码。@dpitch40,如果你回答了你的问题,你应该将该注释变成一个答案并接受它。除了捕获信号的全部目的不只是杀死程序,而是安全地停止它,关闭任何打开的连接。这是否会给您一个适当的方式/时间来完成此操作?