多进程消息队列

本文介绍了Python中多进程消息队列的实现方法,包括使用multiprocessing模块的Queue和Pipe来实现进程间通信,展示了如何通过生产者和消费者模型进行消息传递,并提供了一个具体的线程间消息队列的应用实例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  1. 多进程的消息队列
    消息队列”是在消息的传输过程中保存消息的容器。
    消息队列最经典的用法就是消费者和生成者之间通过消息管道来传递消息,消费者和生成者是不通的进程。生产者往管道中写消息,消费者从管道中读消息。
    操作系统提供了很多机制来实现进程间的通信 ,multiprocessing模块就提供了Queue和Pipe两种方法来实现。
    使用multiprocessing里面的Queue来实现消息队列。通过Mutiprocess里面的Pipe来实现消息队列:
    •Pipe方法返回(conn1, conn2)代表一个管道的两个端。Pipe方法有duplex参数,如果duplex参数为True(默认值),那么这个管道是全双工模式,也就是说conn1和conn2均可收发。duplex为False,conn1只负责接受消息,conn2只负责发送消息。
    •send和recv方法分别是发送和接受消息的方法。close方法表示关闭管道,当消息接受结束以后,关闭管道。

  2. 消息队列pipe
    Python提供了Queue模块来专门实现消息队列
    Queue对象

       Queue.qsize():返回消息队列的当前空间。返回的值不一定可靠。

       Queue.empty():判断消息队列是否为空,返回True或False。同样不可靠。

       Queue.full():类似上边,判断消息队列是否满

       Queue.put(item, block=True, timeout=None):往消息队列中存放消息。block可以控制是否阻塞,timeout指定阻塞时候的等待时间。如果不阻塞或者超时,会引起一 个fullexception。

       Queue.put_nowait(item):相当于put(item, False).

       Queue.get(block=True, timeout=None):获取一个消息,其他同put。
    Queue对象实现一个fifo队列(其他的还有lifo、priority队列,这里不再介绍)。queue只有maxsize一个构造参数,用来指定队列容量,指定为0的时候代表容量无限。主要有以下成员函数,这两个函数用来判断消息对应的任务是否完成。

       Queue.task_done():接受消息的线程通过调用这个函数来说明消息对应的任务已完成。

       Queue.join(): 实际上意味着等到队列为空,再执行别的操作。

    #!/usr/bin/env python
    # -*- coding: utf-8 -*-
    # @Author: lingxiangxiang
     
    import random,threading,time
    from Queue import Queue
    #Producer thread
    class Producer(threading.Thread):
        def __init__(self, t_name, queue):
            threading.Thread.__init__(self,name=t_name)
            self.data=queue
        def run(self):
            for i in range(10):    #随机产生10个数字 ,可以修改为任意大小
                # randomnum=random.randint(1,99)
                print "%s: %s is producing %d to the queue!" % (time.ctime(), self.getName(), i)
                self.data.put(i)  #将数据依次存入队列
                # time.sleep(1)
            print "%s: %s finished!" %(time.ctime(), self.getName())
     
    #Consumer thread
    class Consumer_even(threading.Thread):
        def __init__(self,t_name,queue):
            threading.Thread.__init__(self,name=t_name)
            self.data=queue
        def run(self):
            while 1:
                try:
                    val_even = self.data.get(1,5)  #get(self, block=True, timeout=None) ,1就是阻塞等待,5是超时5秒
                    if val_even%2==0:
                        print "%s: %s is consuming. %d in the queue is consumed!" % (time.ctime(),self.getName(),val_even)
                        time.sleep(2)
                    else:
                        self.data.put(val_even)
                        time.sleep(2)
                except:     #等待输入,超过5秒  就报异常
                    print "%s: %s finished!" %(time.ctime(),self.getName())
                    break
    class Consumer_odd(threading.Thread):
        def __init__(self,t_name,queue):
            threading.Thread.__init__(self, name=t_name)
            self.data=queue
        def run(self):
            while 1:
                try:
                    val_odd = self.data.get(1,5)
                    if val_odd%2!=0:
                        print "%s: %s is consuming. %d in the queue is consumed!" % (time.ctime(), self.getName(), val_odd)
                        time.sleep(2)
                    else:
                        self.data.put(val_odd)
                        time.sleep(2)
                except:
                    print "%s: %s finished!" % (time.ctime(), self.getName())
                    break
    #Main thread
    def main():
        queue = Queue()
        producer = Producer('Pro.', queue)
        consumer_even = Consumer_even('Con_even.', queue)
        consumer_odd = Consumer_odd('Con_odd.',queue)
        producer.start()
        consumer_even.start()
        consumer_odd.start()
        producer.join()
        consumer_even.join()
        consumer_odd.join()
        print 'All threads terminate!'
     
    if __name__ == '__main__':
    main()



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值