详解boost库中的Message Queue

https://www.cnblogs.com/ltm5180/p/4334522.html

 

Message Queue(后文简写成MQ或消息队列)是boost库中用来封装进程间通信的一种实现,同一台机器上的进程或线程可以通过消息队列来进行通迅。消息队列中的消息由优先级、消息长度、消息数据三部分组成。这里需要注意的事,MQ只是简单的将要发送的数据在内存中进行拷贝,所以我们在发送复杂结构或对象时,我们需要将其序列化后再发送,接收端接收时要反序列化,也就是说我们要自己去定义区分一条消息(就是自定义网络通迅协议)。在MQ中,我们可以使用三模式去发送和接收消息:

  1. 阻塞:在发送消息时,若消息队列满了,那么发送接口将会阻塞直到队列没有满。在接收消息时,若队列为空,那么接收接口也会阻塞直到队列不空。
  2. 超时:用户可以自定义超时时间,在超时时间到了,那么发送接口或接收接口都会返回,无论队列满或空
  3. Try:在队列为空或满时,都能立即返回

MQ使用命名的共享内存来实现进程间通信。共享内存换句话来说,就是用户可以指定一个名称来创建一块共享内存,然后像打一个文件一样去打开这块共享内存,同样别的进程也可以根据这个名称来打开这块共享内存,这样一个进程向共享内存中写,另一个进程就可以从共享内存中读。这里两个进程的读写就涉及到同步问题。另外,在创建一个MQ时,我们需要指定MQ的最大消息数量以及消息的最大size。

 

  1. //Create a message_queue. If the queue   
  2. //exists throws an exception   
  3. message_queue mq  
  4.    (create_only         //only create   
  5.    ,"message_queue"     //name   
  6.    ,100                 //max message number   
  7.    ,100                 //max message size   
  8.    );  
  9. using boost::interprocess;  
  10. //Creates or opens a message_queue. If the queue   
  11. //does not exist creates it, otherwise opens it.   
  12. //Message number and size are ignored if the queue   
  13. //is opened   
  14. message_queue mq  
  15.    (open_or_create      //open or create   
  16.    ,"message_queue"     //name   
  17.    ,100                 //max message number   
  18.    ,100                 //max message size   
  19.    );  
  20. using boost::interprocess;  
  21. //Opens a message_queue. If the queue   
  22. //does not exist throws an exception.   
  23. message_queue mq  
  24.    (open_only           //only open   
  25.    ,"message_queue"     //name   
  26.    );  

使用message_queue::remove("message_queue");来移除一个指定的消息队列。

接下来,我们看一个使用消息队列的生产者与消息者的例子。第一个进程做为生产者,第二个进程做为消费者。

生产者进程:

[cpp] view plaincopyprint?

  1. #include <boost/interprocess/ipc/message_queue.hpp>   
  2. #include <iostream>   
  3. #include <vector>   
  4.   
  5. using namespace boost::interprocess;  
  6.   
  7. int main ()  
  8. {  
  9.    try{  
  10.       //Erase previous message queue   
  11.       message_queue::remove("message_queue");  
  12.   
  13.       //Create a message_queue.   
  14.       message_queue mq  
  15.          (create_only               //only create   
  16.          ,"message_queue"           //name   
  17.          ,100                       //max message number   
  18.          ,sizeof(int)               //max message size   
  19.          );  
  20.   
  21.       //Send 100 numbers   
  22.       for(int i = 0; i < 100; ++i){  
  23.          mq.send(&i, sizeof(i), 0);  
  24.       }  
  25.    }  
  26.    catch(interprocess_exception &ex){  
  27.       std::cout << ex.what() << std::endl;  
  28.       return 1;  
  29.    }  
  30.   
  31.    return 0;  
  32. }  
消费者进程:

[cpp] view plaincopyprint?

  1. #include <boost/interprocess/ipc/message_queue.hpp>   
  2. #include <iostream>   
  3. #include <vector>   
  4.   
  5. using namespace boost::interprocess;  
  6.   
  7. int main ()  
  8. {  
  9.    try{  
  10.       //Open a message queue.   
  11.       message_queue mq  
  12.          (open_only        //only create   
  13.          ,"message_queue"  //name   
  14.          );  
  15.   
  16.       unsigned int priority;  
  17.       message_queue::size_type recvd_size;  
  18.   
  19.       //Receive 100 numbers   
  20.       for(int i = 0; i < 100; ++i){  
  21.          int number;  
  22.          mq.receive(&number, sizeof(number), recvd_size, priority);  
  23.          if(number != i || recvd_size != sizeof(number))  
  24.             return 1;  
  25.       }  
  26.    }  
  27.    catch(interprocess_exception &ex){  
  28.       message_queue::remove("message_queue");  
  29.       std::cout << ex.what() << std::endl;  
  30.       return 1;  
  31.    }  
  32.    message_queue::remove("message_queue");  
  33.    return 0;  
  34. }  
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在安卓中判断MessageQueue处理完成可以使用以下方法: 1. 使用Handler的post方法来发送一个Runnable任务到MessageQueue,并在任务中执行需要判断完成的操作。当任务执行完毕时,可以通过回调或其他方式来通知完成。 ```java Handler handler = new Handler(); handler.post(new Runnable() { @Override public void run() { // 执行需要判断完成的操作 // 操作完成后进行回调或其他方式通知完成 } }); ``` 2. 使用Handler的sendMessage方法发送一个Message对象到MessageQueue,并在Message的处理方法中执行需要判断完成的操作。当操作完成后,可以通过回调或其他方式来通知完成。 ```java Handler handler = new Handler() { @Override public void handleMessage(Message msg) { // 执行需要判断完成的操作 // 操作完成后进行回调或其他方式通知完成 } }; Message message = Message.obtain(handler); handler.sendMessage(message); ``` 3. 使用Looper的myQueue方法获取当前线程的MessageQueue对象,并使用MessageQueue的isIdle方法来判断MessageQueue是否处理完成。isIdle方法返回true表示没有待处理的消息。 ```java Looper looper = Looper.myLooper(); if (looper != null) { MessageQueue messageQueue = looper.getQueue(); boolean isIdle = messageQueue.isIdle(); if (isIdle) { // MessageQueue处理完成 } else { // MessageQueue还有待处理的消息 } } ``` 以上是几种常见的判断MessageQueue处理完成的方法,具体选择哪种方法取决于你的需求和场景。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值