python 生产者/消费者

线程在系统中运行时,线程的调度具有一定的透明性,通常程序无法准确预知线程的轮换执行,Python 可通过线程通信来保证线程协调运行。

假设系统中有两个线程,这两个线程分别代表存款者和取钱者,现在假设系统有一种特殊的要求,即要求存款者和取钱者不断地重复存款、取钱的动作,而且要求每当存款者将钱存入指定账户后,取钱者就立即取出该笔钱。不允许存款者连续两次存钱,也不允许取钱者连续两次取钱。

为了实现这种功能,可以借助于 Condition 对象来保持协调。使用 Condition 可以让那些己经得到 Lock 对象却无法继续执行的线程释放 Lock 对象,Condition 对象也可以唤醒其他处于等待状态的线程。

Condition 类提供了如下几个方法:
acquire([timeout])/release():调用 Condition 关联的 Lock 的 acquire() 或 release() 方法。

wait([timeout]):使当前线程进入 Condition 的等待池等待通知并释放锁,直到其他线程调用该 Condition 的 notify() 或 notify_all() 方法来唤醒该线程。在调用该 wait() 方法时可传入一个 timeout 参数,指定该线程最多等待多少秒。

notify():唤醒在该 Condition 等待池中的单个线程并通知它,收到通知的线程将自动调用
notify_all():唤醒在该 Condition 等待池中等待的所有线程并通知它们。

acquire() 方法尝试加锁。如果所有线程都在该 Condition 等待池中等待,则会选择唤醒其中一个线程,选择是任意性的。

实现代码如下:

import threading
import time 
 
 

class Account:
    def __init__(self,balance):
        self._balance = balance 

        # 旗标  控制应该那个线程工作
        # False 表示存钱,True 表示取钱
        self._flag = False 
        self._cond = threading.Condition() 

    def draw(self,amount):
        while True:
            self._cond.acquire()
            
            if self._flag:
                time.sleep(0.01)
                self._balance -= amount 
                print(threading.current_thread(),'draw++',self._balance)
                self._flag = False 
                self._cond.notify_all() 
                self._cond.wait() 
            else:
                print(threading.current_thread(),'draw--',self._balance)
                self._cond.wait() 
                 
                
            


    def deposit(self,amount):
        while True:
            self._cond.acquire()
            if not self._flag:
                time.sleep(0.01)
                self._balance += amount
                print(threading.current_thread(),'deposit++',self._balance)
                self._flag = True 
                self._cond.notify_all() 
                self._cond.wait() 
            else:
                print(threading.current_thread(),'deposit--',self._balance)
                self._cond.wait()
                

a = Account(0)

threading.Thread(target=a.draw,args=(100,)).start()
threading.Thread(target=a.deposit,args=(100,)).start() 

效果如下:存钱、取钱交替执行,threading.Condition 对象的wait() 方法会释放当前线程的锁,并让当前线程进入阻塞状态,故可以不需要调用release() 释放锁。如果先调用wait(),再notify_all() 方法将会导致程序死锁。
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Python模拟生产者/消费者问题是一种常见的多线程问题。生产者线程负责生成数据并将其放入共享队列中,而消费者线程则负责从队列中取出数据并进行处理。这种设计模式可以有效地解决生产者消费者之间的数据同步和互斥问题。 使用Python可以通过线程和队列模块来实现生产者/消费者模式。线程模块可以创建和管理线程,队列模块可以提供线程安全的队列数据结构。 具体实现可以按照以下步骤进行: 1. 导入所需的模块,包括线程和队列模块。 2. 创建一个共享队列,用于生产者消费者之间的数据传递。 3. 定义一个生产者函数,该函数在一个循环中生成数据并将其放入队列中。 4. 定义一个消费者函数,该函数在一个循环中从队列中取出数据并进行处理。 5. 创建生产者线程和消费者线程,并启动它们。 6. 等待线程结束。 以下是一个示例代码来模拟生产者/消费者问题: ```python import threading import queue # 创建共享队列 queue = queue.Queue() # 定义生产者函数 def producer(): while True: data = generate_data() # 生成数据 queue.put(data) # 将数据放入队列中 # 定义消费者函数 def consumer(): while True: data = queue.get() # 从队列中取出数据 process_data(data) # 处理数据 # 创建生产者线程和消费者线程 producer_thread = threading.Thread(target=producer) consumer_thread = threading.Thread(target=consumer) # 启动线程 producer_thread.start() consumer_thread.start() # 等待线程结束 producer_thread.join() consumer_thread.join() ``` 以上代码中,生产者函数(producer)在一个循环中生成数据并将其放入队列中,消费者函数(consumer)在一个循环中从队列中取出数据并进行处理。生产者线程和消费者线程分别启动后,可以并行执行。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值