關於Python線程的Event事件機制

先看官方的Event類註解:

class Event:
    """Class implementing event objects.
    Events manage a flag that can be set to true with the set() method and reset
    to false with the clear() method. The wait() method blocks until the flag is
    true.  The flag is initially false.

    """

    # After Tim Peters' event class (without is_posted())
    def __init__(self):
        self._cond = Condition(Lock())
        self._flag = False

    ...

註解中說明了3個可以使用的方法:set()、wait()、clear()。

set():設置標誌位爲True。(Set the internal flag to true.)

wait():如果當前標誌位是False,則進入阻塞狀態,直到標誌位變爲True,解除阻塞,該方法立即返回。(Block until the internal flag is true.)

clear():設置標誌位爲False。(Reset the internal flag to false.)

 

這3個方法都需要用到,我一開始在項目中忽略了clear(),導致線程無法進入休眠狀態,一直在運行。

下面是正確使用的demo,生產者產生一個數字,消費者讀取這個數字,並打印,進行10次:

from threading import Thread, Event
import time

x = 0

class Producer(Thread):
    def __init__(self, consumer):
        Thread.__init__(self)
        self.consumer = consumer

    def run(self):
        global x
        for i in range(0, 10):
            x = i**2
            self.consumer.wake()
            time.sleep(1)

class Consumer(Thread):
    def __init__(self):
        Thread.__init__(self)
        self.event = Event()

    def wake(self):
        # 設置標誌位(置爲True)
        self.event.set()

    def run(self):
        global x
        count = 10
        while count > 0:
            # 阻塞等待直到標誌位被置爲True
            self.event.wait()
            # 清除標誌位(置爲False),爲下次阻塞等待做準備
            self.event.clear()
            print('Consumer:', time.time(), 'x=', x)
            count -= 1

if __name__ == '__main__':
    c = Consumer()
    c.start()
    Producer(c).start()

測試結果:

Consumer: 1585116237.4874198 x= 0
Consumer: 1585116238.4887447 x= 1
Consumer: 1585116239.4891763 x= 4
Consumer: 1585116240.4904392 x= 9
Consumer: 1585116241.4907174 x= 16
Consumer: 1585116242.4911718 x= 25
Consumer: 1585116243.4913554 x= 36
Consumer: 1585116244.4918528 x= 49
Consumer: 1585116245.492998 x= 64
Consumer: 1585116246.4934428 x= 81

Process finished with exit code 0

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章