Python中的生产者消费者问题
admin
2023-07-31 00:48:31
0

我们将使用Python线程来解决Python中的生产者—消费者问题。这个问题完全不像他们在学校中说的那么难。

如果你对生产者—消费者问题有了解,看这篇博客会更有意义。

为什么要关心生产者—消费者问题:

  • 可以帮你更好地理解并发和不同概念的并发。
  • 信息队列中的实现中,一定程度上使用了生产者—消费者问题的概念,而你某些时候必然会用到消息队列。

当我们在使用线程时,你可以学习以下的线程概念:

  • Condition:线程中的条件。
  • wait():在条件实例中可用的wait()。
  • notify() :在条件实例中可用的notify()。

我假设你已经有这些基本概念:线程、竞态条件,以及如何解决静态条件(例如使用lock)。否则的话,你建议你去看我上一篇文章basics of Threads。

引用维基百科:

生产者的工作是产生一块数据,放到buffer中,如此循环。与此同时,消费者在消耗这些数据(例如从buffer中把它们移除),每次一块。

这里的关键词是“同时”。所以生产者和消费者是并发运行的,我们需要对生产者和消费者做线程分离。

123456789 from threading import Thread class ProducerThread(Thread):    def run(self):        pass class ConsumerThread(Thread):    def run(self):        pass

再次引用维基百科:

这个为描述了两个共享固定大小缓冲队列的进程,即生产者和消费者。

假设我们有一个全局变量,可以被生产者和消费者线程修改。生产者产生数据并把它加入到队列。消费者消耗这些数据(例如把它移出)。

1 queue = []

在刚开始,我们不会设置固定大小的条件,而在实际运行时加入(指下述例子)。

一开始带bug的程序:

123456789101112131415161718192021222324252627282930313233 from threading import Thread, Lockimport timeimport random queue = []lock = Lock() class ProducerThread(Thread):    def run(self):        nums = range(5) #Will create the list [0, 1, 2, 3, 4]        global queue        while True:            num = random.choice(nums) #Selects a random number from list [0, 1, 2, 3, 4]            lock.acquire()            queue.append(num)            print \”Produced\”, num             lock.release()            time.sleep(random.random()) class ConsumerThread(Thread):    def run(self):        global queue        while True:            lock.acquire()            if not queue:                print \”Nothing in queue, but consumer will try to consume\”            num = queue.pop(0)            print \”Consumed\”, num             lock.release()            time.sleep(random.random()) ProducerThread().start()ConsumerThread().start()

运行几次并留意一下结果。如果程序在IndexError异常后并没有自动结束,用Ctrl+Z结束运行。

样例输出:

1234567891011121314 Produced 3Consumed 3Produced 4Consumed 4Produced 1Consumed 1Nothing in queue, but consumer will try to consumeException in thread Thread2:Traceback (most recent call last):  File \”/usr/lib/python2.7/threading.py\”, line 551, in __bootstrap_inner    self.run()  File \”producer_consumer.py\”, line 31, in run    num =-h\”> 31, in run    num =Ό全不像他们在学校中说的那么难。

如果你对生产者—消费者问题有了解,看这篇博客会更有意义。

为什么要关心生产者—消费者问题:

  • 可以帮你更好地理解并发和不同概念的并发。
  • 信息队列中的实现中,一定程度上使用了生产者—消费者问题的概念,而你某些时候必然会用到消息队列。

当我们在使用线程时,你可以学习以下的线程概念:

  • Condition:线程中的条件。
  • wait():在条件实例中可用的wait()。
  • notify() :在条件实例中可用的notify()。

我假设你已经有这些基本概念:线程、竞态条件,以及如何解决静态条件(例如使用lock)。否则的话,你建议你去看我上一篇文章basics of Threads。

引用维基百科:

生产者的工作是产生一块数据,放到buffer中,如此循环。与此同时,消费者在消耗这些数据(例如从buffer中把它们移除),每次一块。

这里的关键词是“同时”。所以生产者和消费者是并发运行的,我们需要对生产者和消费者做线程分离。

123456789 from threading import Thread class ProducerThread(Thread):    def run(self):        pass class ConsumerThread(Thread):    def run(self):        pass

再次引用维基百科:

这个为描述了两个共享固定大小缓冲队列的进程,即生产者和消费者。

假设我们有一个全局变量,可以被生产者和消费者线程修改。生产者产生数据并把它加入到队列。消费者消耗这些数据(例如把它移出)。

1 queue = []

在刚开始,我们不会设置固定大小的条件,而在实际运行时加入(指下述例子)。

一开始带bug的程序:

123456789101112131415161718192021222324252627282930313233 from threading import Thread, Lockimport timeimport random queue = []lock = Lock() class ProducerThread(Thread):    def run(self):        nums = range(5) #Will create the list [0, 1, 2, 3, 4]        global queue        while True:            num = random.choice(nums) #Selects a random number from list [0, 1, 2, 3, 4]            lock.acquire()            queue.append(num)            print \”Produced\”, num             lock.release()            time.sleep(random.random()) class ConsumerThread(Thread):    def run(self):        global queue        while True:            lock.acquire()            if not queue:                print \”Nothing in queue, but consumer will try to consume\”            num = queue.pop(0)            print \”Consumed\”, num             lock.release()            time.sleep(random.random()) ProducerThread().start()ConsumerThread().start()

运行几次并留意一下结果。如果程序在IndexError异常后并没有自动结束,用Ctrl+Z结束运行。

样例输出:

1234567891011121314 Produced 3Consumed 3Produced 4Consumed 4Produced 1Consumed 1Nothing in queue, but consumer will try to consumeException in thread Thread2:Traceback (most recent call last):  File \”/usr/lib/python2.7/threading.py\”, line 551, in __bootstrap_inner    self.run()  File \”producer_consumer.py\”, line 31, in run    num =v>Python

相关内容

热门资讯

Mobi、epub格式电子书如... 在wps里全局设置里有一个文件关联,打开,勾选电子书文件选项就可以了。
500 行 Python 代码... 语法分析器描述了一个句子的语法结构,用来帮助其他的应用进行推理。自然语言引入了很多意外的歧义,以我们...
定时清理删除C:\Progra... C:\Program Files (x86)下面很多scoped_dir开头的文件夹 写个批处理 定...
scoped_dir32_70... 一台虚拟机C盘总是莫名奇妙的空间用完,导致很多软件没法再运行。经过仔细检查发现是C:\Program...
65536是2的几次方 计算2... 65536是2的16次方:65536=2⁶ 65536是256的2次方:65536=256 6553...
小程序支付时提示:appid和... [Q]小程序支付时提示:appid和mch_id不匹配 [A]小程序和微信支付没有进行关联,访问“小...
pycparser 是一个用... `pycparser` 是一个用 Python 编写的 C 语言解析器。它可以用来解析 C 代码并构...
微信小程序使用slider实现... 众所周知哈,微信小程序里面的音频播放是没有进度条的,但最近有个项目呢,客户要求音频要有进度条控制,所...
Apache Doris 2.... 亲爱的社区小伙伴们,我们很高兴地向大家宣布,Apache Doris 2.0.0 版本已于...
python清除字符串里非数字... 本文实例讲述了python清除字符串里非数字字符的方法。分享给大家供大家参考。具体如下: impor...