1. 程式人生 > >python-執行緒的暫停, 恢復, 退出

python-執行緒的暫停, 恢復, 退出

原文地址為: python-執行緒的暫停, 恢復, 退出

  我們都知道python中可以是threading模組實現多執行緒, 但是模組並沒有提供暫停, 恢復和停止執行緒的方法, 一旦執行緒物件呼叫start方法後, 只能等到對應的方法函式執行完畢. 也就是說一旦start後, 執行緒就屬於失控狀態. 不過, 我們可以自己實現這些. 一般的方法就是迴圈地判斷一個標誌位, 一旦標誌位到達到預定的值, 就退出迴圈. 這樣就能做到退出執行緒了. 但暫停和恢復執行緒就有點難了, 我一直也不清除有什麼好的方法, 直到我看到threading中Event物件的wait方法的描述時.

wait([timeout])

Block until the internal flag
is true. If the internal flag is true on entry, return immediately. Otherwise, block until another thread calls set() to set the flag to true, or until the optional timeout occurs.

阻塞, 直到內部的標誌位為True時. 如果在內部的標誌位在進入時為True時, 立即返回. 否則, 阻塞直到其他執行緒呼叫set()方法將標準位設為True, 或者到達了可選的timeout時間.


When the timeout argument
is present and not None, it should be a floating point number specifying a timeout for the operation in seconds (or fractions thereof).

This method returns the internal flag on exit, so it will always
return True except if a timeout is given and the operation times out.

當給定了timeout引數且不為None, 它應該是一個浮點數,以秒為單位指定操作的超時(或是分數)。

此方法在退出時返回內部標誌,因此除非給定了超時且操作超時,否則它將始終返回True。


Changed
in version 2.7: Previously, the method always returned None.

2.7版本以前, 這個方法總會返回None.

 

 

  利用wait的阻塞機制, 就能夠實現暫停和恢復了, 再配合迴圈判斷標識位, 就能實現退出了, 下面是程式碼示例:

 

#!/usr/bin/env python
#
coding: utf-8

import threading
import time


class Job(threading.Thread):

def __init__(self, *args, **kwargs):
super(Job, self).
__init__(*args, **kwargs)
self.
__flag = threading.Event() # 用於暫停執行緒的標識
self.__flag.set() # 設定為True
self.__running = threading.Event() # 用於停止執行緒的標識
self.__running.set() # 將running設定為True

def run(self):
while self.__running.isSet():
self.
__flag.wait() # 為True時立即返回, 為False時阻塞直到內部的標識位為True後返回
print time.time()
time.sleep(
1)

def pause(self):
self.
__flag.clear() # 設定為False, 讓執行緒阻塞

def resume(self):
self.
__flag.set() # 設定為True, 讓執行緒停止阻塞

def stop(self):
self.
__flag.set() # 將執行緒從暫停狀態恢復, 如何已經暫停的話
self.__running.clear() # 設定為False

 

下面是測試程式碼:

a = Job()
a.start()
time.sleep(
3)
a.pause()
time.sleep(
3)
a.resume()
time.sleep(
3)
a.pause()
time.sleep(
2)
a.stop()

 

測試的結果:

 

 

  這完成了暫停, 恢復和停止的功能. 但是這裡有一個缺點: 無論是暫停還是停止, 都不是瞬時的, 必須等待run函式內部的執行到達標誌位判斷時才有效. 也就是說操作會滯後一次.

  但是這有時也不一定是壞事. 如果run函式中涉及了檔案操作或資料庫操作等, 完整地執行一次後再退出, 反而能夠執行剩餘的資源釋放操作的程式碼(例如各種close). 不會出現程式的檔案操作符超出上限, 資料庫連線未釋放等尷尬的情況.

 


轉載請註明本文地址: python-執行緒的暫停, 恢復, 退出