生产者消费者问题

下面是生产者消费者问题

生产者-消费者问题和Queue/queue模块

  • 生产者生产商品,将商品放入到类似队列的数据结构中,生产的时间不确定

  • 消费者消费商品,消费的时间不确定

  • 使用Queue模块创建队列,生产者线程放入商品,消费者线程消费商品

  • 下表列出Queue/queue模块的常用属性

  • 属性 描述
    Queue/queue模块的类 ******
    Queue(maxsize=0) 创建一个先进先出队列,若给定最大值,则当队列没有空间时阻塞,否则为无限队列
    LifoQueue(maxsize=0) 创建一个后进先出队列,若给定最大值,则空间满时阻塞,否则为无限队列
    PriorityQueue(maxsize=0) 创建一个优先级队列,若给定最大值,当没有空间时阻塞,否则为无限队列
    Queue/queue异常
    Empty 当对空队列调用get*()方法时抛出的异常
    Full 当对已满的队列调用put*()方法是抛出的异常
    Queue/queue对象方法
    qsize() 返回队列大小(该值为近似值)
    empty() 若队列为空,返回True,否则返回False
    full() 若队列为满,返回True,否则为False
    put(item,block=True,timeout=None) 将item放入队列,如果block为True且timeout=None,则在有可用之前阻塞,如果timeout为正值,则最多阻塞timeout秒,block=False,则抛出Empty异常
    put_nowait(item) 和put(item,False)一样
    get(block=True,timeout=None) 从队列中获得元素,若给定block则一直阻塞到有可用的元素为止
    get_nowait() 和get(False)相同
    task_done() 用于表示队列中的某个元素已执行完成,该方法会被下面的join()使用
    join() 在队列中所有元素执行完毕并调用上面的task_done信号之前,保持阻塞

  • 生产者消费者问题

    from time import sleep,ctime
    import threading
    
    loops=(4,2)
    
    class MyThread(threading.Thread):
        def __init__(self,func,args,name=''):
            threading.Thread.__init__(self)
            self.func=func
            self.args=args
            self.name=name
    
        def run(self):
            return self.func(*self.args)
    
    def loop(nloop,nsec):
        print("loop {} started at {} ".format(nloop,ctime()))
        sleep(nsec)
        print("loop {} started at {} ".format(nloop,ctime()))
    
    def main():
        print("Main started at {}".format(ctime()))
        threads=[]
        count=range(len(loops))
    
        for i in count:
            t=MyThread(loop,(i,loops[i]),loop.__name__)
            threads.append(t)
    
        for i in count:
            threads[i].start()
    
        for i in count:
            threads[i].join()
    
        print("All done at {}".format(ctime()))
    
    if __name__ == '__main__':
        main()
        
    #——————————————上述为自定义的MyTread类,下面为生产者消费者问题——————————————————————
    from time import ctime,sleep
    from random import randint
    from e import MyThread
    from queue import Queue
    
    def writeQ(queue):  #将生产的对象放入队列中
        print("Producing Q")
        queue.put("xxx",1)
        print("size now {}".format(queue.qsize()))
    
    def readQ(queue):   #消费在队列中的对象
        print("consuming Q size now  {}".format(queue.qsize()))
        val=queue.get(1)
    
    def write(queue,loops):  #根据loops生产随机数量的对象
        for i in (range(loops)):
            writeQ(queue)
            sleep(randint(1,3))
    
    def read(queue,loops):   #根据loops消费随机数量的对象
        for i in range(loops):
            readQ(queue)
            sleep(randint(2,5))
    
    funcs=[write,read]
    nfuncs=range(len(funcs))
    
    def main():
        nloops=randint(2,5)  #设置进行的随机次数
        threads=[]
        q=Queue(32)  #设置最大队列
        for i in nfuncs:
            t=MyThread(funcs[i],(q,nloops),funcs[i].__name__)
            threads.append(t)
    
        for i in nfuncs:
            threads[i].start()
    
        for i in nfuncs:
            threads[i].join()
    
        print("All Done!!!")
    
    if __name__ == '__main__':
        main()
        
    '''显示结果如下:
    func write run at Sat May 23 08:19:39 2020
    Producing Q
    size now 1
    func read run at Sat May 23 08:19:39 2020
    consuming Q size now  1
    Producing Q
    size now 1
    Producing Q
    size now 2
    consuming Q size now  2
    func write finished at Sat May 23 08:19:46 2020
    consuming Q size now  1
    func read finished at Sat May 23 08:19:51 2020
    All Done!!!'''
    
    
    • 注意不管是生产还是消费,每次只生产或消费一个对象
    • 注意到write对象的暂停时间较短保证了消费时尽可能的可以拥有消费对象,而不是从空队列中取值

上述就是生产者消费者问题,希望对各位有所帮助!

你可能感兴趣的:(笔记,python,python,queue,多线程)