condition类里内置了一把RLock锁,有acquire方法和release方法,还有wait,notify,notifyAll方法,
使用acquire方法可以获得RLock锁
使用wait方法就会放掉锁并处于阻塞状态,等其他线程中有使用notify方法时,在wait前的acquire方法处继续线程(注意:而不是紧随wait后面执行)。
notify会唤醒一个wait,但是不会立即跳转到另一个线程的wait处,必须在notify后使用release才能跳转到正在wait的线程的wait语句处。不然不释放锁,wait就继续不了,必须先确认肯定有一个wait时,才可以notify,否则会报错。
import threading import time import sys # 方便调用sys.stdout.write方法取代print方法,因为print具有线程不安全性(换行符会有被拆分输出的机率) condition = threading.Condition() item = [] # 列表表示大盘子,最多可以放20个包子 item_id = 0 # 包子的号码 class Producer(threading.Thread): def __init__(self, name, n): threading.Thread.__init__(self, name=name, args=n) # 需要先调用父类的构造函数 self.name = name self.n = n # 要做的包子数 def run(self): global item, item_id while self.n != 0: # 准备开始做一共做n个包子 condition.acquire() # 只在读取或改变公有变量/成员时获取线程锁 if len(item) == 20: sys.stdout.write(f‘桌子放满了,{self.name}暂停做包子\n‘) condition.wait() item.append(item_id) # 做好的包子放进盘子里 item_id += 1 # 包子号递增 sys.stdout.write(f"{self.name}做好了一个包子,放盘子里了{item}\n") if len(item) == 1: condition.notify() # 如果盘里现在是1个包子,则通知顾客吃包子 self.n -= 1 # 需要做的包子数递减 condition.release() # 改变公有变量/成员后立即释放锁,以减少线程阻塞时间 time.sleep(3) # 3秒钟做一个包子 else: sys.stdout.write(f"{self.name}做包子任务完成了\n") class Consumer(threading.Thread): def __init__(self, name, n): threading.Thread.__init__(self, name=name, args=n) # 需要先调用父类的构造函数 self.name = name self.n = n # 要吃的包子数 def run(self): global item while self.n != 0: condition.acquire() # 只在读取或改变公有变量/成员时获取线程锁 if len(item) == 0: sys.stdout.write(f‘{self.name}等待包子中\n‘) condition.wait() del item[0] # 销毁先做好的包子 sys.stdout.write(f‘{self.name}吃掉了一个包子{item}\n‘) if len(item) == 19: condition.notify() # 如果现在盘子里有19个包子,则通知生产者可以继续生产了 self.n -= 1 condition.release() # 改变公有变量/成员后立即释放锁,以减少线程阻塞时间 time.sleep(1) # 一秒钟吃一个包子 else: sys.stdout.write(f‘{self.name}包子吃够了\n‘) if __name__ == ‘__main__‘: threads = [] for i in range(1, 3): # 先建立两个顾客 threads.append(Consumer(‘C‘ + str(i), 10)) # 每个顾客准备消费10个包子 for i in range(1, 6): # 再建立5个包子生产者 threads.append(Producer(‘P‘+str(i), 4)) # 每个生产者各生产4个包子 for t in threads: t.start() for t in threads: t.join() print("完毕")
python条件同步线程threading.Condition
原文:https://www.cnblogs.com/bohua320/p/15313351.html