使用Python实现生产者消费者问题

之前用C++写过一篇生产者消费者的实现。

生产者和消费者主要是处理互斥和同步的问题:

队列作为缓冲区,需要互斥操作

队列中没有产品,消费者需要等待,直到生产者放入产品并通知它。队列慢的情况类似。

这里我使用list模拟Python标准库的Queue,这里我设置一个大小限制为5:

SyncQueue.py

from threading import Lock
from threading import Condition
class Queue():
    def __init__(self):
        self.mutex = Lock()
        self.full = Condition(self.mutex)
        self.empty = Condition(self.mutex)
        self.data = []

    def push(self, element):
        self.mutex.acquire()
        while len(self.data) >= 5:
            self.empty.wait()
            
        self.data.append(element)
        self.full.notify()    
        self.mutex.release()


    def pop(self):
        self.mutex.acquire()
        while len(self.data) == 0:
            self.full.wait()
        data = self.data[0]
        self.data.pop(0)
        self.empty.notify()
        self.mutex.release()

        return data

if __name__ == __main__:
    q = Queue()
    q.push(10)
    q.push(2)
    q.push(13)

    print q.pop()
    print q.pop()
    print q.pop()

这是最核心的代码,注意里面判断条件要使用while循环。

接下来是生产者进程,producer.py

from threading import Thread
from random import randrange
from time import sleep
from SyncQueue import Queue

class ProducerThread(Thread):
    def __init__(self, queue):
        Thread.__init__(self)
        self.queue = queue
    def run(self):
        while True:
            data = randrange(0, 100)
            self.queue.push(data)
            print push %d % (data)
            sleep(1)

if __name__ == __main__:
    q = Queue()
    t = ProducerThread(q)
    t.start()
    t.join()

消费者,Condumer.py

from threading import Thread
from time import sleep
from SyncQueue import Queue

class ConsumerThread(Thread):
    def __init__(self, queue):
        Thread.__init__(self)
        self.queue = queue
    def run(self):
        while True:
            data = self.queue.pop()
            print pop %d % (data)
            sleep(1)

if __name__ == __main__:
    q = Queue()
    t = ConsumerThread(q)
    t.start()
    t.join()

最后我们写一个车间类,可以指定线程数量:

from SyncQueue import Queue
from Producer import ProducerThread
from Consumer import ConsumerThread

class WorkShop():
    def __init__(self, producerNums, consumerNums):
        self.producers = []
        self.consumers = []
        self.queue = Queue()
        self.producerNums = producerNums
        self.consumerNums = consumerNums
    def start(self):
        for i in range(self.producerNums):
            self.producers.append(ProducerThread(self.queue))
        for i in range(self.consumerNums):
            self.consumers.append(ConsumerThread(self.queue))
        for i in range(len(self.producers)):
            self.producers[i].start()
        for i in range(len(self.consumers)):
            self.consumers[i].start()
        for i in range(len(self.producers)):
            self.producers[i].join()
        for i in range(len(self.consumers)):
            self.consumers[i].join()

if __name__ == __main__:
    w = WorkShop(3, 4)
    w.start()

最后写一个main模块:

from WorkShop import WorkShop

if __name__ == __main__:
    w = WorkShop(2, 3)
    w.start()

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。