2

下面是我的测试代码。
使用 python2.7 运行时,它显示程序在所有派生线程完成之前不会收到任何信号。
在使用 python3.2 时,只有主线程的 sigintHandler 被调用。
我对 python 如何处理线程和信号感到困惑,那么如何生成一个线程并在该线程中进行信号处理?有可能吗?

from __future__ import print_function
from threading import Thread
import signal, os, sys
from time import sleep

def sigintHandler(signo, _):
    print("signal %d caught"%signo)

def fn():
    print("thread sleeping")
    sleep(10)
    print("thread awakes")

signal.signal(signal.SIGINT, sigintHandler)

ls = []
for i in range(5):
    t = Thread(target=fn)
    ls.append(t)
    t.start()

print("All threads up, pid=%d"%os.getpid())
for i in ls:
    i.join()

while True:
    sleep(20)
4

2 回答 2

0

您说:在使用 python3.2 时,只有主线程的 sigintHandler 被调用。

我认为这是对的。从这里开始:信号和线程

Python 信号处理程序始终在 Python 主线程中执行,即使信号是在另一个线程中接收到的。这意味着信号不能用作线程间通信的手段。您可以改用 threading 模块中的同步原语。

此外,只允许主线程设置新的信号处理程序。

于 2013-10-31T07:39:12.657 回答
0

Python 不会异步处理信号。当您在 python 中安装信号处理程序时,运行时会安装一个仅设置标志的 C 信号处理程序存根。解释器检查字节码指令之间的标志,然后调用 python 信号处理程序。这意味着信号处理程序只能在字节码操作之间运行。如果主 python 线程正在执行 C 代码,则在当前操作完成之前,它将无法处理信号。SIGINT(即 control-C)有一些规定可以中止阻塞的 IO,但仅限于主线程。

也就是说,如果你想根据信号的接收在线程中执行代码,方法是在主线程中接收信号,然后通过队列向工作线程发送消息。您必须确保您的主线程永远不会在不可中断的调用中阻塞。在 python 2.7 中,join 是不可中断的(正如您所发现的)。在更高版本的python中它是。

于 2013-11-07T19:38:19.830 回答