2013-10-31 57 views
1

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

如果您在范围(10):sleep(1)'中用'替换'sleep(10)',我是否有区别? – shx2

+0

刚刚试过,但没有区别@ shx2 – adamsmith

回答

0

Python不会异步处理信号。当您在python中安装信号处理程序时,运行时会安装一个只设置标志的C信号处理程序存根。解释器检查字节码指令之间的标志,然后调用python信号处理程序。这意味着信号处理程序只能在字节码操作之间运行。如果主python线程正在执行C代码,它将无法处理信号,直到当前操作完成。 SIGINT(即control-C)有一些规定可以中止阻塞的IO,但只能在主线程中使用。这就是说,如果你想基于接收到的信号在一个线程中执行代码,其实现方法是在主线程中接收信号,然后通过队列发送消息给工作线程。你将不得不确保你的主线程永远不会阻塞在一个不可中断的电话。在Python 2.7中,连接不是可以间断的(就像你发现的那样)。在更高版本的Python中,它是。

0

你说:虽然与python3.2,只有主线程的sigintHandler被调用。

我认为是对的。从这里开始:Signals and threads

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

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

+0

我的意图不是做线程间通信,而是为了异步处理信号。 – adamsmith

相关问题