亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

詳解python如何優(yōu)雅地關閉線程

 更新時間:2024年03月27日 11:08:32   作者:__彎弓__  
這篇文章主要介紹了python如何優(yōu)雅地關閉線程,在并發(fā)編程中,我們可能會創(chuàng)建新線程,并在其中運行任務,可能由于一些原因,決定停止該線程,那么應該如何正確關閉線程呢?文中給了詳細的解決方法,需要的朋友可以參考下

在并發(fā)編程中,我們可能會創(chuàng)建新線程,并在其中運行任務,可能由于一些原因,決定停止該線程。例如:

  • 不再需要線程任務的結果了。
  • 應用程序正在關閉。
  • 線程執(zhí)行可能已經(jīng)出現(xiàn)了異常

Threading 模塊的 Thread 類并沒有提供關閉線程的方法。如果不正確關閉子線程,可能遇到如下問題:

  • 中止主線程后,子線程仍然在運行,成為僵尸進程
  • 子線程打開的文件未能正確關閉,造成數(shù)據(jù)丟失
  • 子線程打開的數(shù)據(jù)庫,未能提交更新,造成數(shù)據(jù)丟失

那么應該如何正確關閉線程呢?

1. Python 默認關閉線程的方式

線程對象創(chuàng)建后,調用start(方法運行, 執(zhí)行結束后,自動關閉。如下面的示例代碼:

#!/usr/bin/python
# -*- coding: UTF-8 -*-

import threading    #導入threading 模塊
import time

# 定義任務函數(shù) print_time
def print_time ( threadName ,delay ):
    count = 0
    while count < 5:
        time.sleep(delay)
        count += 1
        print("%s: %s \n" % (threadName,time.ctime(time.time())))

# 定義任務函數(shù) print_cube
def print_cube(num):
    #pring cube
    print("Cube:{} \n".format(num*num*num))
 
# 創(chuàng)建兩個線程
if __name__ == "__main__":
        # 創(chuàng)建兩個子線程
        t1 = threading.Thread( target=print_cube,args=(10,))
        t2 = threading.Thread( target=print_time,args=("Thread-2",4,))
        #start threads
        t1.start()   # start 后,子線程開始運行
        t2.start()
        t1.join()     #join 命令:讓主線程暫停運行,等待子線程運行結束。
        t2.join()
        print("Done") # The statement is executed after sub threads done

2. 如何優(yōu)雅地關閉線程?

上節(jié)的例子,線程執(zhí)行時間短,很快可以結束,所以主線程可以等待其結束。但是如果子線程執(zhí)行的是1個耗時任務,如提供1個服務,或執(zhí)行1個Monitor 任務,子線程內可能存在永久循環(huán),這時子線程對象運行start()后,就一直處理運行狀態(tài)。

在WIndows系統(tǒng),如果應用程序直接退出,子線程自然也被強行中止,但子線程正在執(zhí)行的任務可能會受影響,如正在存取的文件可能正確關閉,造成數(shù)據(jù)丟失等。
在Linux系統(tǒng),如果應用程序直接退出,如使用kill命令殺死進程,未正確關閉的子線程可能仍在運行,成為僵尸進程。

那么如何優(yōu)雅地停止子線程呢?思路有兩個:

1) 通過設置全局狀態(tài)變量來關閉線程

2) 通過 threading.Event 對象來關閉線程

下面示例展示兩種方法的實現(xiàn)過程

2.1. 使用全局變量來關閉線程

實現(xiàn)步驟:

  • 在線程內添加狀態(tài)變量
  • 線程循環(huán)體內,檢測狀態(tài)變量,如果為False ,退出循環(huán)。
  • 主線程需要關閉線程時,將子線程對象的狀態(tài)變量置為False即可。

2.1.1 關閉 thread類實現(xiàn)的線程

class CountdownTask:
      
    def __init__(self):
          self._running = True   # 定義線程狀態(tài)變量
      
	def terminate(self):
	    self._running = False 
	      
	def run(self, n):
	    # run方法的主循環(huán)條件加入對狀態(tài)變量的判斷
	    while self._running and n > 0:
	        print('T-minus', n)
	        n -= 1
	        time.sleep(5)
	    print("thread is ended") 
  
c = CountdownTask()
th = Thread(target = c.run, args =(10, ))
th.start()
# 對于耗時線程,沒必要再用join()方法了,注意主線程通常也需要有個監(jiān)控循環(huán)
# … any code … 
# Signal termination
q = input("please press any key to quit ")
c.terminate() 

2.1.2 關閉函數(shù)式線程

關閉函數(shù)式線程,可以用全局變量做狀態(tài)變量

import threading
import time
 
def run():
    while True:
        print('thread running')
        global stop_threads
        if stop_threads:
            break
 
stop_threads = False
t1 = threading.Thread(target = run)
t1.start()
time.sleep(1)
stop_threads = True
t1.join()
print('thread killed')


2.2. 使用 threading.Event 對象關閉子線程

2.2.1 Event 機制工作原理

Event 是線程間通信的一種方式。其作用相當于1個全局flag,主線程通過控制 event 對象狀態(tài),來協(xié)調子線程步調。

使用方式

  1. 主線程創(chuàng)建 event 對象,并將其做為參數(shù)傳給子線程
  2. 主線程可以用set()方法將event 對象置為true, 用clear()方法將其置為false。
  3. 子線程循環(huán)體內,檢查 event 對象的值,如果為 True, 則退出循環(huán)。
  4. 子線程,可使用 event.wait() 將阻塞當前子進程,直至event 對象被置為true.

event 類的常用方法

  • set() 設置 True
  • clear() 設置 False,
  • wait() 使進程等待,直到flag被改為true.
  • is_set() 查詢 event 對象,如被設置為真,則返回True, 否則返回False.
if event.is_set():
     # do something before end worker 
     break

這種方式的優(yōu)點是,Event對象是線程安全的,而且速度更快,推薦使用這種方式關閉耗時線程。

2.2.2 完整代碼:

from time import sleep
from threading import Thread
from threading import Event
 
# define task function
def task(event):
    # execute a task in a loop
    for i in range(100):
        # block for a moment
        sleep(1)
        # check for stop
        if event.is_set():
            # 在此添加退出前要做的工作,如保存文件等
            break
        # report a message
        print('Worker thread running...')
    print('Worker is ended')
 
# create the event
event = Event()
# create a thread 
thread = Thread(target=task, args=(event,))
# start the new thread
thread.start()
# block for a while
sleep(3)
# stop the worker thread
print('Main stopping thread')
event.set()
# 這里是為了演示,實際開發(fā)時,主進程有事件循環(huán),耗時函數(shù)不需要調用join()方法
thread.join()

子線程執(zhí)行其任務循環(huán),它每次循環(huán)都會檢查event對象,該對象保持 false,就不會觸發(fā)線程停止。

當主線程調用event對象的 set() 方法后,在子線程循環(huán)體內,調用event對象is_set()方法,發(fā)現(xiàn)event 對象為True后, 立即退出任務循環(huán),結束運行。

到此這篇關于詳解python如何優(yōu)雅地關閉線程的文章就介紹到這了,更多相關python關閉線程內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • python計算Content-MD5并獲取文件的Content-MD5值方式

    python計算Content-MD5并獲取文件的Content-MD5值方式

    這篇文章主要介紹了python計算Content-MD5并獲取文件的Content-MD5值方式,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-04-04
  • python中的正斜杠與反斜杠實例驗證

    python中的正斜杠與反斜杠實例驗證

    這篇文章主要介紹了python中的正斜杠與反斜杠實例驗證,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-03-03
  • 教你用Python寫安卓游戲外掛

    教你用Python寫安卓游戲外掛

    本篇文章主要給教給大家如何用python這個語言寫出安卓游戲的輔助外掛以及思路講解,有興趣的朋友跟著學習下吧。
    2018-01-01
  • python指定路徑斜杠與反斜杠遇到的問題

    python指定路徑斜杠與反斜杠遇到的問題

    這篇文章主要介紹了python指定路徑斜杠與反斜杠遇到的問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-03-03
  • 使用Python自定義創(chuàng)建的Log日志模塊

    使用Python自定義創(chuàng)建的Log日志模塊

    這篇文章主要介紹了使用Python自定義創(chuàng)建的Log日志模塊,日志文件是用于記錄系統(tǒng)操作事件的文件集合,可分為事件日志和消息日志。具有處理歷史數(shù)據(jù)、診斷問題的追蹤以及理解系統(tǒng)的活動等重要作用,需要的朋友可以參考下
    2023-07-07
  • Python性能調優(yōu)的十個小技巧總結

    Python性能調優(yōu)的十個小技巧總結

    大家好,今天這篇文章關于Python性能調優(yōu)的10個小技巧,每天花5-10分鐘閱讀我的文章,對你技術提升一定會有幫助。喜歡記得收藏以防迷路
    2021-11-11
  • numpy中hstack vstack stack concatenate函數(shù)示例詳解

    numpy中hstack vstack stack concatenate函數(shù)示例詳解

    這篇文章主要為大家介紹了numpy中hstack vstack stack concatenate函數(shù)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-02-02
  • 教你編譯pjsip源碼的方法

    教你編譯pjsip源碼的方法

    通過本文教大家如何編譯pjsip源碼,本文通過圖文并茂的形式給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友參考下吧
    2021-10-10
  • python捕獲警告的三種方法

    python捕獲警告的三種方法

    這篇文章主要介紹了python捕獲警告的三種方法,幫助大家更好的理解和學習使用python,感興趣的朋友可以了解下
    2021-03-03
  • Python-re中search()函數(shù)的用法詳解(查找ip)

    Python-re中search()函數(shù)的用法詳解(查找ip)

    這篇文章主要介紹了Python-re中search()函數(shù)的用法-----查找ip,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-03-03

最新評論