Python:阻止信号传播到子线程

时间:2016-07-26 17:11:27

标签: python multithreading signals

import threading
import time

def worker(i):

    while True:
        try:
            print i
            time.sleep(10)
            break
        except Exception, msg:
            print msg



threads = []
for i in range(10):
    t1 = threading.Thread(target=worker, args=(i,))
    threads.append(t1)

for t in threads:
    t.start()


print "started all threads... waiting to be finished"
for t in threads:
    t.join()

如果我在线程运行时按^ C,线程是否获得SIGINT?
如果这是真的,我可以从调用程序线程做什么来阻止它将SIGINT传播到正在运行的线程?

调用者线程中的

信号处理程序会阻止它吗? 或者我需要每个线程的信号处理程序?

2 个答案:

答案 0 :(得分:0)

Python's docs中所述,您应该使用属性守护程序

  

守护程序:一个布尔值,指示此线程是否为守护程序   线程(True)与否(False)。必须在start()之前设置   调用,否则引发RuntimeError。它的初始值是   继承自创建线程;主线程不是守护进程   线程,因此在主线程中创建的所有线程都默认为   守护进程=假。

     

当没有活动的非守护程序线程时,整个Python程序退出   左

     

2.6版中的新功能。

要控制CTRL + C信号,您应该捕获它,使用 signal.signal(signal_number,handler)功能更改处理程序。子进程继承SIGINT的信号处理程序。

import threading
import time
import signal


def worker(i):
    while True:
        try:
            print(i)
            time.sleep(10)
            break
        except Exception as msg:
            print(msg)


def signal_handler(signal, frame):
    print('You pressed Ctrl+C!')
    print("I will wait for all threads... waiting to be finished")
    for t in threads:
        t.join()

signal.signal(signal.SIGINT, signal_handler)

threads = []
for i in range(10):
    t1 = threading.Thread(target=worker, args=(i,))
    threads.append(t1)

for t in threads:
    t.start()

print("started all threads... waiting to be finished")
for t in threads:
    t.join()

答案 1 :(得分:0)

  

如果我在线程运行时按^ C,线程是否会获得SIGINT?

没有。在Python中,只有主线程接收SIGINT。

不幸的是,我不知道python源中的好地方或链接到的文档,但是你可以看到这是一个简单的测试:

import threading
import time

def worker():
    while True:
        print('Worker working')
        time.sleep(0.5)
        pass


worker_thread = threading.Thread(target=worker)
worker_thread.start()

while True:
    print('Parent parenting')
    time.sleep(0.5)

使用^ C发送SIGINT后,您将看到主线程被杀死(不再是父母的父母和#39;日志)并且子线程继续运行。

在您的示例中,您的子线程退出是因为您在{10}之后break循环中while