python-線程的暫停, 恢復, 退出

  咱們都知道python中能夠是threading模塊實現多線程, 可是模塊並無提供暫停, 恢復和中止線程的方法, 一旦線程對象調用start方法後, 只能等到對應的方法函數運行完畢. 也就是說一旦start後, 線程就屬於失控狀態. 不過, 咱們能夠本身實現這些. 通常的方法就是循環地判斷一個標誌位, 一旦標誌位到達到預約的值, 就退出循環. 這樣就能作到退出線程了. 但暫停和恢復線程就有點難了, 我一直也不清除有什麼好的方法, 直到我看到threading中Event對象的wait方法的描述時.python

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). 不會出現程序的文件操做符超出上限, 數據庫鏈接未釋放等尷尬的狀況.spa

相關文章
相關標籤/搜索