python 多线程笔记(5)-- 生产者/消费者模式

简介: 我们已经知道,对公共资源进行互斥访问,可以使用Lock上锁,或者使用RLock去重入锁。   但是这些都只是方便于处理简单的同步现象,我们甚至还不能很合理的去解决使用Lock锁带来的死锁问题。

 

我们已经知道,对公共资源进行互斥访问,可以使用Lock上锁,或者使用RLock去重入锁。

 

但是这些都只是方便于处理简单的同步现象,我们甚至还不能很合理的去解决使用Lock锁带来的死锁问题。

要解决更复杂的同步问题,就必须考虑别的办法了。

 

threading提供的Condition对象提供了对复杂线程同步问题的支持。

Condition被称为条件变量,除了提供与Lock类似的acquire和release方法外,还提供了wait和notify方法。

 

使用Condition的主要方式为:

线程首先acquire一个条件变量,然后判断一些条件。如果条件不满足则wait;如果条件满足,进行一些 处理改变条件后,通过notify方法通知其他线程,其他处于wait状态的线程接到通知后会重新判断条件。不断的重复这一过程,从而解决复杂的同步问 题。

 

下面我们通过很著名的“生产者-消费者”模型来来演示下,在Python中使用Condition实现复杂同步。

 

生产者和消费者,各一个线程,双方将会围绕products来产生同步问题,首先是2个生成者生产products ,而接下来的10个消费者将会消耗products

import threading
import time
 
condition = threading.Condition()
products = 0
 
class Producer(threading.Thread):
    '''生产者'''
    ix = [0] # 生产者实例个数
             # 闭包,必须是数组,不能直接 ix = 0
    def __init__(self, ix=0):
        super().__init__()
        self.ix[0] += 1
        self.setName('生产者' + str(self.ix[0]))
 
    def run(self):
        global condition, products
        
        while True:
            if condition.acquire():
                if products < 10:
                    products += 1;
                    print("{}:库存不足(10-)。我努力生产了1件产品,现在产品总数量 {}".format(self.getName(), products))
                    condition.notify()
                else:
                    print("{}:库存充足(10+)。让我休息会儿,现在产品总数量 {}".format(self.getName(), products))
                    condition.wait();
                condition.release()
                time.sleep(2)


class Consumer(threading.Thread):
    '''消费者'''
    ix = [0] # 消费者实例个数
             # 闭包,必须是数组,不能直接 ix = 0
    def __init__(self):
        super().__init__()
        self.ix[0] += 1
        self.setName('消费者' + str(self.ix[0]))
 
    def run(self):
        global condition, products
        
        while True:
            if condition.acquire():
                if products > 1:
                    products -= 1
                    print("{}:我消费了1件产品,现在产品数量 {}".format(self.getName(), products))
                    condition.notify()
                else:
                    print("{}:只剩下1件产品,我停止消费。现在产品数量 {}".format(self.getName(), products))
                    condition.wait();
                condition.release()
                time.sleep(2)



if __name__ == "__main__":
    for i in range(2):
        p = Producer()
        p.start()
 
    for i in range(10):
        c = Consumer()
        c.start()

 

另外:

Condition对象的构造函数可以接受一个Lock/RLock对象作为参数,

如果没有指定,则Condition对象会在内部自行创建一个 RLock;

除了notify方法外,Condition对象还提供了notifyAll方法,可以通知waiting池中的所有线程尝试acquire 内部锁。

由于上述机制,处于waiting状态的线程只能通过notify方法唤醒,所以notifyAll的作用在于防止有线程永远处于沉默状态。

 

目录
相关文章
|
3月前
|
数据采集 存储 JSON
Python爬取知乎评论:多线程与异步爬虫的性能优化
Python爬取知乎评论:多线程与异步爬虫的性能优化
|
3月前
|
数据采集 监控 调度
干货分享“用 多线程 爬取数据”:单线程 + 协程的效率反超 3 倍,这才是 Python 异步的正确打开方式
在 Python 爬虫中,多线程因 GIL 和切换开销效率低下,而协程通过用户态调度实现高并发,大幅提升爬取效率。本文详解协程原理、实战对比多线程性能,并提供最佳实践,助你掌握异步爬虫核心技术。
|
4月前
|
JSON 算法 Java
打造终端里的下载利器:Python实现可恢复式多线程下载器
在数字时代,大文件下载已成为日常需求。本文教你用Python打造专业级下载器,支持断点续传、多线程加速、速度限制等功能,显著提升终端下载体验。内容涵盖智能续传、多线程分块下载、限速控制及Rich库构建现代终端界面,助你从零构建高效下载工具。
274 1
|
3月前
|
数据采集 存储 Java
多线程Python爬虫:加速大规模学术文献采集
多线程Python爬虫:加速大规模学术文献采集
|
4月前
|
数据采集 网络协议 前端开发
Python多线程爬虫模板:从原理到实战的完整指南
多线程爬虫通过并发请求大幅提升数据采集效率,适用于大规模网页抓取。本文详解其原理与实现,涵盖任务队列、线程池、会话保持、异常处理、反爬对抗等核心技术,并提供可扩展的Python模板代码,助力高效稳定的数据采集实践。
208 0
|
12月前
|
安全 数据处理 开发者
Python中的多线程编程:从入门到精通
本文将深入探讨Python中的多线程编程,包括其基本原理、应用场景、实现方法以及常见问题和解决方案。通过本文的学习,读者将对Python多线程编程有一个全面的认识,能够在实际项目中灵活运用。
|
9月前
|
并行计算 安全 Java
Python GIL(全局解释器锁)机制对多线程性能影响的深度分析
在Python开发中,GIL(全局解释器锁)一直备受关注。本文基于CPython解释器,探讨GIL的技术本质及其对程序性能的影响。GIL确保同一时刻只有一个线程执行代码,以保护内存管理的安全性,但也限制了多线程并行计算的效率。文章分析了GIL的必要性、局限性,并介绍了多进程、异步编程等替代方案。尽管Python 3.13计划移除GIL,但该特性至少要到2028年才会默认禁用,因此理解GIL仍至关重要。
595 16
Python GIL(全局解释器锁)机制对多线程性能影响的深度分析
|
8月前
|
Python
python3多线程中使用线程睡眠
本文详细介绍了Python3多线程编程中使用线程睡眠的基本方法和应用场景。通过 `time.sleep()`函数,可以使线程暂停执行一段指定的时间,从而控制线程的执行节奏。通过实际示例演示了如何在多线程中使用线程睡眠来实现计数器和下载器功能。希望本文能帮助您更好地理解和应用Python多线程编程,提高程序的并发能力和执行效率。
283 20
|
8月前
|
数据采集 Java 数据处理
Python实用技巧:轻松驾驭多线程与多进程,加速任务执行
在Python编程中,多线程和多进程是提升程序效率的关键工具。多线程适用于I/O密集型任务,如文件读写、网络请求;多进程则适合CPU密集型任务,如科学计算、图像处理。本文详细介绍这两种并发编程方式的基本用法及应用场景,并通过实例代码展示如何使用threading、multiprocessing模块及线程池、进程池来优化程序性能。结合实际案例,帮助读者掌握并发编程技巧,提高程序执行速度和资源利用率。
378 0
|
10月前
|
机器学习/深度学习 数据采集 TensorFlow
使用Python实现智能食品消费者行为分析的深度学习模型
使用Python实现智能食品消费者行为分析的深度学习模型
270 4

推荐镜像

更多