1. 程式人生 > >python多執行緒join方法導致不能接收訊號

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篇文章,我們一起來聊聊多執行緒開發當中死鎖的問題。 死鎖 死鎖的原理非常簡單,用一句話就可以描述完。就是當多執行緒訪問多個鎖的時候,不同的鎖被不同的執行緒持有,它們都在等待其他執行緒釋放出鎖來,於是便