2016-07-26 41 views
1
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傳播到正在運行的線程?Python:阻止信號傳播到子線程

調用者線程中的信號處理程序會阻止它嗎?
還是我需要每個線程的信號處理程序?

回答

0

Python's docs提到,你應該使用屬性守護

守護進程:一個布爾值,指示線程是否是守護線程 (True)還是沒有(假)。這必須在start()被調用前設置爲 ,否則會引發RuntimeError。它的初始值是從創建線程繼承的 ;主線程不是守護進程 線程,因此在主線程中創建的所有線程默認爲 daemon = False。

當沒有活動的非守護進程線程 離開時,整個Python程序將退出。

版本2.6中的新功能。

要控制CTRL + C信號,你應該抓住它改變了處理器與signal.signal(signal_number,處理程序)功能。子進程繼承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() 
+0

好嗎?..這與信號有什麼關係? – ealeon

+0

我想明確加入他們。 – ealeon

+0

如果子線程繼承了信號處理程序,每個線程都會嘗試加入線程(列表)?對於線程中的t:t.join()是一次或所有線程調用的塊嗎? – ealeon

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) 

後您發送SIGINT與^ C,您將看到主線程被終止(不再有'父母父母'日誌)並且子線程繼續運行。

在你的例子中,你的子線程退出,因爲你在012秒後從while循環中取出break