欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Python中用Ctrl+C終止多線程程序的問(wèn)題解決

 更新時(shí)間:2013年03月30日 14:23:14   投稿:shangke  
花了一天時(shí)間用python為服務(wù)寫(xiě)了個(gè)壓力測(cè)試。很簡(jiǎn)單,多線程向服務(wù)器發(fā)請(qǐng)求。但寫(xiě)完之后發(fā)現(xiàn)如果中途想停下來(lái),按Ctrl+C達(dá)不到效果,自然想到要用信號(hào)處理函數(shù)捕捉信號(hào),使線程都停下來(lái),問(wèn)題解決的方法請(qǐng)往下看:

復(fù)制代碼 代碼如下:

#!/bin/env python
 # -*- coding: utf-8 -*-
 #filename: peartest.py
 
 import threading, signal
 
 is_exit = False
 
 def doStress(i, cc):
     global is_exit
     idx = i
     while not is_exit:
         if (idx < 10000000):
             print "thread[%d]: idx=%d"%(i, idx)
             idx = idx + cc
         else:
             break
     print "thread[%d] complete."%i
 
 def handler(signum, frame):
     global is_exit
     is_exit = True
     print "receive a signal %d, is_exit = %d"%(signum, is_exit)
 
 if __name__ == "__main__":
     signal.signal(signal.SIGINT, handler)
     signal.signal(signal.SIGTERM, handler)
     cc = 5
     for i in range(cc):
         t = threading.Thread(target=doStress, args=(i,cc))
         t.start()

上面是一個(gè)模擬程序,并不真正向服務(wù)發(fā)送請(qǐng)求,而代之以在一千萬(wàn)以內(nèi),每個(gè)線程每隔并發(fā)數(shù)個(gè)(cc個(gè))打印一個(gè)整數(shù)。很明顯,當(dāng)所有線程都完成自己的任務(wù)后,進(jìn)程會(huì)正常退出。但如果我們中途想退出(試想一個(gè)壓力測(cè)試程序,在中途已經(jīng)發(fā)現(xiàn)了問(wèn)題,需要停止測(cè)試),該腫么辦?你當(dāng)然可以用ps查找到進(jìn)程號(hào),然后kill -9殺掉,但這樣太繁瑣了,捕捉Ctrl+C是最自然的想法。上面示例程序中已經(jīng)捕捉了這個(gè)信號(hào),并修改全局變量is_exit,線程中會(huì)檢測(cè)這個(gè)變量,及時(shí)退出。

但事實(shí)上這個(gè)程序并不work,當(dāng)你按下Ctrl+C時(shí),程序照常運(yùn)行,并無(wú)任何響應(yīng)。網(wǎng)上搜了一些資料,明白是python的子線程如果不是daemon的話,主線程是不能響應(yīng)任何中斷的。但設(shè)為daemon后主線程會(huì)隨之退出,接著整個(gè)進(jìn)程很快就退出了,所以還需要在主線程中檢測(cè)各個(gè)子線程的狀態(tài),直到所有子線程退出后自己才退出,因此上例29行之后的代碼可以修改為:

復(fù)制代碼 代碼如下:

threads=[]
     for i in range(cc):
         t = threading.Thread(target=doStress, args=(i, cc))
         t.setDaemon(True)
         threads.append(t)
         t.start()
     for i in range(cc):
         threads[i].join()

重新試一下,問(wèn)題依然沒(méi)有解決,進(jìn)程還是沒(méi)有響應(yīng)Ctrl+C,這是因?yàn)閖oin()函數(shù)同樣會(huì)waiting在一個(gè)鎖上,使主線程無(wú)法捕獲信號(hào)。因此繼續(xù)修改,調(diào)用線程的isAlive()函數(shù)判斷線程是否完成:

復(fù)制代碼 代碼如下:

while 1:
         alive = False
         for i in range(cc):
             alive = alive or threads[i].isAlive()
         if not alive:
             break

這樣修改后,程序完全按照預(yù)想運(yùn)行了:可以順利的打印每個(gè)線程應(yīng)該打印的所有數(shù)字,也可以中途用Ctrl+C終結(jié)整個(gè)進(jìn)程。完整的代碼如下:

復(fù)制代碼 代碼如下:

#!/bin/env python
 # -*- coding: utf-8 -*-
 #filename: peartest.py
 
 import threading, signal
 
 is_exit = False
 
 def doStress(i, cc):
     global is_exit
     idx = i
     while not is_exit:
         if (idx < 10000000):
             print "thread[%d]: idx=%d"%(i, idx)
             idx = idx + cc
         else:
             break
     if is_exit:
         print "receive a signal to exit, thread[%d] stop."%i
     else:
         print "thread[%d] complete."%i
 
 def handler(signum, frame):
     global is_exit
     is_exit = True
     print "receive a signal %d, is_exit = %d"%(signum, is_exit)
 
 if __name__ == "__main__":
     signal.signal(signal.SIGINT, handler)
     signal.signal(signal.SIGTERM, handler)
     cc = 5
     threads = []
     for i in range(cc):
         t = threading.Thread(target=doStress, args=(i,cc))
         t.setDaemon(True)
         threads.append(t)
         t.start()
     while 1:
         alive = False
         for i in range(cc):
             alive = alive or threads[i].isAlive()
         if not alive:
             break

1.把所有子線程設(shè)為Daemon;
2.使用isAlive()函數(shù)判斷所有子線程是否完成,而不是在主線程中用join()函數(shù)等待完成;
3.寫(xiě)一個(gè)響應(yīng)Ctrl+C信號(hào)的函數(shù),修改全局變量,使得各子線程能夠檢測(cè)到,并正常退出。

相關(guān)文章

  • Python最基本的數(shù)據(jù)類型以及對(duì)元組的介紹

    Python最基本的數(shù)據(jù)類型以及對(duì)元組的介紹

    這篇文章主要介紹了Python最基本的數(shù)據(jù)類型以及對(duì)元組的介紹,來(lái)自于IBM官方網(wǎng)站技術(shù)文檔,需要的朋友可以參考下
    2015-04-04
  • Python 語(yǔ)法錯(cuò)誤:"SyntaxError: invalid character in identifier"原因及解決方法

    Python 語(yǔ)法錯(cuò)誤:"SyntaxError: invalid charac

    本文給大家分享Python 語(yǔ)法錯(cuò)誤:“SyntaxError: invalid character in identifier“,原因及解決方法,文末給大家補(bǔ)充介紹了Python出現(xiàn)SyntaxError: invalid syntax的原因總結(jié),感興趣的朋友跟隨小編一起學(xué)習(xí)吧
    2023-02-02
  • Python統(tǒng)計(jì)學(xué)一數(shù)據(jù)的概括性度量詳解

    Python統(tǒng)計(jì)學(xué)一數(shù)據(jù)的概括性度量詳解

    這篇文章主要介紹了Python統(tǒng)計(jì)學(xué)一數(shù)據(jù)的概括性度量詳解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2020-03-03
  • Python基礎(chǔ)之變量基本用法與進(jìn)階詳解

    Python基礎(chǔ)之變量基本用法與進(jìn)階詳解

    這篇文章主要介紹了Python基礎(chǔ)之變量基本用法與進(jìn)階,結(jié)合實(shí)例形式詳細(xì)分析了Python變量引用、可變和不可變類型、局部變量和全局變量等相關(guān)原理與使用技巧,需要的朋友可以參考下
    2020-01-01
  • Python的幾個(gè)高級(jí)語(yǔ)法概念淺析(lambda表達(dá)式閉包裝飾器)

    Python的幾個(gè)高級(jí)語(yǔ)法概念淺析(lambda表達(dá)式閉包裝飾器)

    本文主要記錄自己對(duì)幾個(gè)高級(jí)語(yǔ)法概念的理解:匿名函數(shù)、lambda表達(dá)式、閉包、裝飾器。這幾個(gè)概念并非Python特有,但本文只限于用Python做說(shuō)明
    2016-05-05
  • 基于scrapy的redis安裝和配置方法

    基于scrapy的redis安裝和配置方法

    今天小編就為大家分享一篇基于scrapy的redis安裝和配置方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2018-06-06
  • PyCharm常用配置和常用插件(小結(jié))

    PyCharm常用配置和常用插件(小結(jié))

    這篇文章主要介紹了PyCharm常用配置和常用插件(小結(jié)),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-02-02
  • python XlsxWriter模塊創(chuàng)建aexcel表格的實(shí)例講解

    python XlsxWriter模塊創(chuàng)建aexcel表格的實(shí)例講解

    今天小編就為大家分享一篇python XlsxWriter模塊創(chuàng)建aexcel表格的實(shí)例講解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2018-05-05
  • 解決python3報(bào)錯(cuò)之takes?1?positional?argument?but?2?were?given問(wèn)題

    解決python3報(bào)錯(cuò)之takes?1?positional?argument?but?2?were?gi

    這篇文章主要介紹了解決python3報(bào)錯(cuò)之takes?1?positional?argument?but?2?were?given問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-03-03
  • Python try except異常捕獲機(jī)制原理解析

    Python try except異常捕獲機(jī)制原理解析

    這篇文章主要介紹了Python try except異常捕獲機(jī)制原理解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-04-04

最新評(píng)論