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()
  • 相关阅读:
    ADB高级应用
    struts2 结合extjs实现的一个登录实例
    css3中关于伪类的使用
    漫谈并发编程(三):共享受限资源
    awk依照多个分隔符进行切割
    3星|《财经天下周刊》2017年21期:海外购几乎是亚马逊中国的最后一根救命稻草
    3星|《迷失的盛宴:中国保险产业1978-2014》:序言比正文精彩
    3星|《超级运营术》:互联网社区运营老手经验谈
    3星|《百年流水线》:流水线与工业、社会、艺术的交互史
    5星|戴蒙德《为什么有的国家富裕,有的国家贫穷》:为什么有的国家能发展出好制度
  • 原文地址:https://www.cnblogs.com/inevermore/p/4189958.html
Copyright © 2011-2022 走看看