1. 使用条件进行线程同步

python-parallel-programming-cookbook-cn 使用条件进行线程同步

条件指的是应用程序状态的改变。这是另一种同步机制,其中某些线程在等待某一条件发生,其他的线程会在该条件发生的时候进行通知。一旦条件发生,线程会拿到共享资源的唯一权限。

解释条件机制最好的例子还是生产者-消费者问题。在本示例中,只要缓存不满,生产者一直向缓存生产;只要缓存不空,消费者一直从缓存取出(之后销毁)。当缓冲队列不为空的时候,生产者将通知消费者;当缓冲队列不满的时候,消费者将通知生产者。

#!/usr/bin/python3
#!--*-- coding:utf-8 --*--
from threading import Thread, Condition
import time

items = []
condition = Condition()

class consumer(Thread):
    def __init__(self):
        Thread.__init__(self)

    def consume(self):
        global condition
        global items
        condition.acquire() #消费者通过拿到锁来修改共享的资源 items[]
        if len(items) == 0: #如果list的长度为0,那么消费者就进入等待状态
            condition.wait()
            print("Consumer notify : no item to consume")
        items.pop() #通过 pop 操作消费一个item
        print("Consumer notify : consumed 1 item")
        print("Consumer notify : items to consume are " + str(len(items)))
        
        #消费者的状态被通知给生产者,同时共享资源释放
        condition.notify()
        condition.release()

        
    def run(self):
        for i in range(0, 20):
            time.sleep(2)
            self.consume()

            
class producer(Thread):
    def __init__(self):
        Thread.__init__(self)

    def produce(self):
        global condition
        global items
        #生产者拿到共享资源,然后确认缓冲队列是否已满
        #这里,缓冲队列最大可以存放10个item
        condition.acquire()
        if len(items) == 10:#如果已经满了,那么生产者进入等待状态,直到被唤醒
            condition.wait()
            print("Producer notify : items producted are " + str(len(items)))
            print("Producer notify : stop the production!!")
        items.append(1)
        print("Producer notify : total items producted " + str(len(items)))
        
        #如果队列没有满,就生产1个item,通知状态并释放资源
        condition.notify()
        condition.release()

        
    def run(self):
        for i in range(0, 20):
            time.sleep(1)
            self.produce()

            
if __name__ == "__main__":
    producer = producer()
    consumer = consumer()
    producer.start()
    consumer.start()
    producer.join()
    consumer.join()

如,

2. 使用事件进行线程同步

python-parallel-programming-cookbook-cn 使用事件进行线程同步

事件是线程之间用于通讯的对象。有的线程等待信号,有的线程发出信号。基本上事件对象都会维护一个内部变量,可以通过 set() 方法设置为 true ,也可以通过 clear() 方法设置为 falsewait() 方法将会阻塞线程,直到内部变量为 true

#!/usr/bin/python3
#!--*-- coding: utf-8 --*--

import time
from threading import Thread, Event
import random

items = []
event = Event()

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

    def run(self):
        while True:
            time.sleep(2)
            self.event.wait()
            item = self.items.pop()
            print('Consumer notify : %d popped from list by %s' % (item, self.name))

            
class producer(Thread):
    def __init__(self, items, event):
        Thread.__init__(self)
        self.items = items
        self.event = event

    def run(self):
        global item
        for i in range(100):
            time.sleep(2)
            item = random.randint(0, 256)
            self.items.append(item)
            print('Producer notify : item N° %d appended to list by %s' % (item, self.name))
            print('Producer notify : event set by %s' % self.name)
            self.event.set()
            print('Produce notify : event cleared by %s '% self.name)
            self.event.clear()

            
if __name__ == '__main__':
    t1 = producer(items, event)
    t2 = consumer(items, event)
    t1.start()
    t2.start()
    t1.join()
    t2.join()

生产者和消费者认识:

Last modification:June 10th, 2022 at 04:57 pm