python多執行緒join方法導致不能接收訊號
今天寫一個小工具,開啟多個執行緒,在子執行緒裡迴圈執行任務,發現不能退出程式,然後折騰了半天,還是退出不了,最後發現,原來是個bug
先上簡化了的程式碼:
import sys import threading import signal import time class myThread(threading.Thread): def __init__(self): threading.Thread.__init__(self) def run(self): while True: time.sleep(1) def handler(signum, frame): print("exit") sys.exit() if __name__ == "__main__": signal.signal(signal.SIGINT, handler) threads = [] for _ in range(0,2): t = myThread() t.setDaemon(True) threads.append(t) t.start() for _ in range(0,2): t.join() # while True:pass
主執行緒裡開啟了兩個子執行緒,子執行緒啥事都不幹,醒了就睡,睡醒了接著睡,如此迴圈往復。並將它們設為daemon執行緒,
按我的理解daemon執行緒就是指當主執行緒程式碼執行完退出後,那麼daemon子執行緒也會結束任務並退出,而非daemon執行緒會不管主執行緒,它會一如既往的執行自己的任務,直到結束才退出,當所有執行緒都退出了,那麼這個程序就結束了。。
主執行緒註冊了一個SIGINT訊號,當接收到這個訊號就退出主執行緒,ctr+c就向這個主執行緒傳送SIGINT訊號,然後按照這個流程,當按下ctr+c的時候應該列印exit後退出程序,然後什麼事情都沒發生。。
然後查資料發現這居然是一個bug,我的天。詳細地址:https://bugs.python.org/issue1167930
當主執行緒join並且子執行緒沒有結束的時候,會阻塞在那,而且不會接受任何訊號。。
然而這個bug他們並沒有修復,只是建議用timeout引數來規避。。
更奇怪的是,python3(我用的3.4)卻沒有這個bug,join的時候,按下ctr+c可以正常退出程序,上面程式碼可以直接用python3執行,看來是在python3中把這個問題修復了,至於python2為啥沒修復就不知道了,也許有什麼難言的苦衷吧,(好象是修復bug會導致其它問題)。。
網上有很多解決辦法,但是一眼看上去有點複雜,我想如果主執行緒不使用join,而是使用一個while迴圈掛在那,當然後讓主執行緒退出了,子執行緒也就推出了。
試驗了一下沒問題:
import sys
import threading
import signal
import time
class myThread(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
def run(self):
while True:
time.sleep(1)
def handler(signum, frame):
print("exit")
sys.exit()
if __name__ == "__main__":
signal.signal(signal.SIGINT, handler)
threads = []
for _ in range(0,2):
t = myThread()
t.setDaemon(True)
threads.append(t)
t.start()
# for _ in range(0,2):
# t.join()
while True:
time.sleep(1)
本人出於個人興趣,建立了一個個人公眾號,每天篩選國外網友發現的有趣的事情推送到公眾號,歡迎關注!
相關推薦
python多執行緒join方法導致不能接收訊號
今天寫一個小工具,開啟多個執行緒,在子執行緒裡迴圈執行任務,發現不能退出程式,然後折騰了半天,還是退出不了,最後發現,原來是個bug 先上簡化了的程式碼: import sys import threading import signal import time c
Python多執行緒使用方法
import threading #Python多執行緒模組 import time def run(num): print 'Hi, I am thread %s..lalala' % num time.sleep(1) for i in ra
JAVA多執行緒 join() 方法詳解及應用場景
在某些情況下,主執行緒建立並啟動了子執行緒,如果子執行緒中需要進行大量的耗時運算,主執行緒往往將早於子執行緒結束之前結束,如果主執行緒想等待子執行緒執行完畢後,獲得子執行緒中的處理完的某個資料,就要用
java多執行緒join方法
在某些情況下,主執行緒建立並啟動了子執行緒,如果子執行緒中需要進行大量的耗時運算,主執行緒往往將早於子執行緒結束之前結束,如果主執行緒想等待子執行緒執行完畢後,獲得子執行緒中的處理完的某個
多執行緒-join方法(主執行緒等待子執行緒執行完畢)
多執行緒中的join方法 join主要的作用就是讓主執行緒 等待 子執行緒 執行完畢之後,才讓主執行緒繼續執行。 話不多說,直接看程式碼例子就好。 父執行緒 package com.luoy.Thread.join; public class Fa
java多執行緒-join方法詳解(附面試題)
本文對java Thread中join()方法進行介紹,join()的作用是讓“主執行緒”等待“子執行緒”結束之後才能繼續執行,大家參考使用吧 本章涉及到的內容包括: 1. join()
python 多執行緒 join 的 細節問題 注意使用事項
threads=[] f=[fast,slow] l=len(f) for i in range(l): t=MyThread(f[i],(),str(i)) threads.append(t) for i in range(l): thread
Java 多執行緒 join和interrupt 方法
簡述: 使用Java多執行緒中join和interrupt函式 《Java程式設計思想》 P669 ~ P670 一個執行緒可以再其他執行緒上呼叫join()方法,其效果是等待一段時間直到第二個執行緒結束才繼續執行。 如果某個執行緒在另一個執行緒t上呼叫t.join(), 此
Python 多執行緒 thread join() 的作用
原文地址 在 Python 的多執行緒程式設計中,在例項程式碼中經常有 thread1.join()這樣的程式碼。那麼今天咱們用實際程式碼來解釋一下 join 函式的作用。 join的原理就是依次檢驗執行緒池中的執行緒是否結束,沒有結束就阻塞直到執行緒結束,如果結束則跳轉執行下一
Python基礎(四)--- Python多執行緒介紹,開啟執行緒的三種方式,time模組,join,Daemon,Lock、Rlock,事件機制,Timer
一、多執行緒介紹 --------------------------------------------------------- 1.threading用於提供執行緒相關的操作,執行緒是應用程式中工作的最小單元。 2.python當前版本的多執行緒庫沒有實現優先順序、執行緒組,執
python多執行緒中的join()
先看一個例子,該例子沒用到join。 新增一個執行緒,輸出“start”和“finish”標記執行緒的開始和結束。執行緒added_thread和執行緒main同時執行,其中added_thread消耗較長的時間(通過執行緒sleep模擬)。mian執行結束後
Python多執行緒中的join函式的使用與含義
wechat:812716131 ------------------------------------------------------ 技術交流群請聯絡上面wechat ----------------------------------------------
Python多執行緒中join函式與setDaemon函式使用說明
在Python多執行緒程式設計的時候,經常需要用到join函式和setDaemon函式。之前對這兩個函式一直理解不是很到位。今天查閱了很多資料,對兩個函式的認識更加的深入一些了。 join([timeout])可以參考Python文件說明。大概意思就
Python多執行緒的理解和使用(一)Threading中join()函式的理解
1. 多執行緒的概念 多執行緒類似於同時執行多個不同程式,多執行緒執行有如下優點: 使用執行緒可以把佔據長時間的程式中的任務放到後臺去處理。 使用者介面可以更加吸引人,這樣比如使用者點選了一個按鈕去觸發某些事件的處理,可以彈出一個進度條來顯示處理的進度 程式的執行速
python多執行緒中daemon的屬性方法
我們看官方介紹是這樣的: 意思就是說:這個屬性為一個布林值,表示是否為一個守護程序,且這個屬性設定必須線上程的start方法開始之前呼叫。它的值繼承自主執行緒,主執行緒的daemon為False且所有從主執行緒建立的執行緒都是daemon = False 。 下面一句
Python 多執行緒 多程序 全域性直譯器鎖GIL join
Python 程式碼的執行由Python 虛擬機器(也叫直譯器主迴圈)來控制。Python 在設計之初就考慮到要在主迴圈中,同時只有一個執行緒在執行,就像單CPU 的系統中執行多個程序那樣,記憶體中可以存放多個程式,但任意時刻,只有一個程式在CPU 中執行。同樣地,雖然Py
python多執行緒程式設計之Queue---put/get 方法的阻塞
python 中,佇列是執行緒間最常用的交換資料的形式。Queue模組是提供佇列操作的模組,雖然簡單易用,但是不小心的話,還是會出現一些意外。 1. 阻塞模式導致資料汙染 import Queue q = Queue.Queue(10) for
Python多執行緒中阻塞(join)與鎖(Lock)的使用誤區
關於阻塞主執行緒 join的錯誤用法 Thread.join() 作用為阻塞主執行緒,即在子執行緒未返回的時候,主執行緒等待其返回然後再繼續執行. join不能與start在迴圈裡連用 以下為錯誤程式碼,程式碼建立了5個執行緒,然後用一個迴圈啟用執行緒,
徹底理解Python多執行緒中的setDaemon與join【配有GIF示意】
在進行Python多執行緒程式設計時, join() 和 setDaemon() 是最常用的方法,下面說說兩者的用法和區別。 1、join () 例子:主執行緒A中,建立了子執行緒B,並且在主執行緒A中呼叫了B.join(), 那麼,主執行緒A會在呼叫的地方阻塞,
Python | 多執行緒死鎖問題的巧妙解決方法
本文始發於個人公眾號:**TechFlow**,原創不易,求個關注 今天是Python專題的第25篇文章,我們一起來聊聊多執行緒開發當中死鎖的問題。 死鎖 死鎖的原理非常簡單,用一句話就可以描述完。就是當多執行緒訪問多個鎖的時候,不同的鎖被不同的執行緒持有,它們都在等待其他執行緒釋放出鎖來,於是便