如何在Python中使用单独的线程进行异步信号处理 [英] How to use a separate thread for asynchronous signal handling in python

查看:131
本文介绍了如何在Python中使用单独的线程进行异步信号处理的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Below is my test code.
When running with python2.7 it shows that the program won't receive any signal until all spawned threads finish.
While with python3.2, only the main thread's sigintHandler gets called.
I'am confused with how python handles threads and signal, so how do I spawn a thread and do signal handling within that thread? Is it possible at all?

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)

推荐答案

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

Python doesn't handle signals asynchronously. When you install a signal handler in python, the runtime installs a C signal handler stub that just sets a flag. The interpreter checks the flag between bytecode instructions and then invokes the python signal handler. That means that signals handlers can only run between bytecode operations. If the main python thread is executing C code, it won't be able to handle signals until the current operation completes. There is some provision for SIGINT (i.e., control-C) to abort blocked IO, but only in the main thread.

也就是说,如果要基于接收到的信号在线程中执行代码,执行该操作的方法是在主线程中接收信号,然后通过Queue向工作线程发送消息.您将必须确保您的主线程永远不会在不可中断的调用中阻塞.在python 2.7中,join不可互操作(如您所知).在更高版本的python中.

That said, if you want to execute code in a thread based on receipt of a signal, the way to do it is to receive the signal in the main thread then send a message to the worker thread via a Queue. You will have to make sure that your main thread never blocks in a non-interruptible call. In python 2.7, join is not interuptable (as you have discovered). In later versions of python it is.

这篇关于如何在Python中使用单独的线程进行异步信号处理的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆