最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Python中用Ctrl+C終止多線程程序的問題解決

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

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

但事實(shí)上這個(gè)程序并不work,當(dāng)你按下Ctrl+C時(shí),程序照常運(yùn)行,并無任何響應(yīng)。網(wǎng)上搜了一些資料,明白是python的子線程如果不是daemon的話,主線程是不能響應(yīng)任何中斷的。但設(shè)為daemon后主線程會隨之退出,接著整個(gè)進(jìn)程很快就退出了,所以還需要在主線程中檢測各個(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()

重新試一下,問題依然沒有解決,進(jìn)程還是沒有響應(yīng)Ctrl+C,這是因?yàn)閖oin()函數(shù)同樣會waiting在一個(gè)鎖上,使主線程無法捕獲信號。因此繼續(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.寫一個(gè)響應(yīng)Ctrl+C信號的函數(shù),修改全局變量,使得各子線程能夠檢測到,并正常退出。

相關(guān)文章

  • Python3中urlencode和urldecode的用法詳解

    Python3中urlencode和urldecode的用法詳解

    今天小編就為大家分享一篇Python3中urlencode和urldecode的用法詳解,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2019-07-07
  • python文件讀取read及readlines兩種方法使用詳解

    python文件讀取read及readlines兩種方法使用詳解

    這篇文章主要為大家介紹了python文件讀取read及readlines兩種方法的使用示例及區(qū)別詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-07-07
  • Python與Node.js之間實(shí)現(xiàn)通信的JSON數(shù)據(jù)接收發(fā)送

    Python與Node.js之間實(shí)現(xiàn)通信的JSON數(shù)據(jù)接收發(fā)送

    Python和Node.js是兩個(gè)流行且功能強(qiáng)大的編程語言,它們之間使用JSON格式進(jìn)行數(shù)據(jù)交換是一種高效和靈活的方式,本文將詳細(xì)介紹如何在Python和Node.js之間通過JSON進(jìn)行數(shù)據(jù)通信,包括發(fā)送和接收J(rèn)SON數(shù)據(jù)以及一些常見的交互示例代碼
    2024-01-01
  • Python實(shí)現(xiàn)WGS84火星百度及web墨卡托四種坐標(biāo)系相互轉(zhuǎn)換

    Python實(shí)現(xiàn)WGS84火星百度及web墨卡托四種坐標(biāo)系相互轉(zhuǎn)換

    主流被使用的地理坐標(biāo)系并不統(tǒng)一,常用的有WGS84、GCJ02(火星坐標(biāo)系)、BD09(百度坐標(biāo)系)以及百度地圖中保存矢量信息的web墨卡托,本文利用Python編寫相關(guān)類以實(shí)現(xiàn)4種坐標(biāo)系統(tǒng)之間的互相轉(zhuǎn)換
    2023-08-08
  • Python程序控制語句用法實(shí)例分析

    Python程序控制語句用法實(shí)例分析

    這篇文章主要介紹了Python程序控制語句用法,結(jié)合實(shí)例形式分析了Python流程控制語句的條件、循環(huán)以及函數(shù)、類、文件、異常處理等相關(guān)操作使用技巧,需要的朋友可以參考下
    2020-01-01
  • 利用Python繪制酷炫的3D地圖

    利用Python繪制酷炫的3D地圖

    pyecharts是一款將python與echarts結(jié)合的強(qiáng)大的數(shù)據(jù)可視化工具。本文將為大家介紹如何利用pyecharts繪制酷炫的3D地圖,感興趣的小伙伴可以試一試
    2022-03-03
  • 分享一下Python數(shù)據(jù)分析常用的8款工具

    分享一下Python數(shù)據(jù)分析常用的8款工具

    Python是數(shù)據(jù)處理常用工具,可以處理數(shù)量級從幾K至幾T不等的數(shù)據(jù),具有較高的開發(fā)效率和可維護(hù)性,還具有較強(qiáng)的通用性和跨平臺性,這里就為大家分享幾個(gè)不錯(cuò)的數(shù)據(jù)分析工具,需要的朋友可以參考下
    2018-04-04
  • 小白教你PyCharm從下載到安裝再到科學(xué)使用PyCharm2020最新激活碼

    小白教你PyCharm從下載到安裝再到科學(xué)使用PyCharm2020最新激活碼

    這篇文章主要介紹了PyCharm最新版從下載到安裝再到科學(xué)使用PyCharm2020最新激活碼,需要的朋友可以參考下
    2020-09-09
  • Python實(shí)現(xiàn)調(diào)用攝像頭拍攝照片

    Python實(shí)現(xiàn)調(diào)用攝像頭拍攝照片

    這篇文章主要為大家詳細(xì)介紹了如何利用Python實(shí)現(xiàn)調(diào)用攝像頭拍攝照片以及郵箱收集功能,文中的示例代碼講解詳細(xì),感興趣的可以動手嘗試一下
    2022-06-06
  • 深入Python解釋器理解Python中的字節(jié)碼

    深入Python解釋器理解Python中的字節(jié)碼

    這篇文章深入Python解釋器、從其對字節(jié)碼的處理過程來詳解Python中的字節(jié)碼,需要的朋友可以參考下
    2015-04-04

最新評論

满洲里市| 长寿区| 深圳市| 星子县| 分宜县| 西和县| 崇信县| 阜新市| 城步| 伊通| 盖州市| 游戏| 开原市| 合山市| 富阳市| 湖口县| 巴塘县| 萨嘎县| 平江县| 天等县| 绩溪县| 双江| 襄汾县| 潞西市| 醴陵市| 多伦县| 射洪县| 昌邑市| 蚌埠市| 巴林左旗| 平乡县| 通城县| 五常市| 荆州市| 遵化市| 海口市| 湟源县| 莲花县| 汤阴县| 格尔木市| 高碑店市|