zoukankan      html  css  js  c++  java
  • 使用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()
  • 相关阅读:
    读完此文让你了解各个queue的原理
    借汇编之力窥探String背后的数据结构奥秘
    汇编高手带你玩转字符串,快上车!
    语雀调研
    产品技能一:抽象能力
    我所认知的敏捷开发
    产品经理需要的技能,我有吗?
    孙正义采访:接下来的30年,一切将被重新定义
    5G小白鼠
    goto语句为啥不受待见
  • 原文地址:https://www.cnblogs.com/inevermore/p/4189958.html
Copyright © 2011-2022 走看看