ACE生产消费者队列就是消息队列

来源:互联网 发布:运营商大数据 编辑:程序博客网 时间:2024/06/03 18:54

ACE—Message一 Queue在Windows和Linux的config文件中都没有定义"ACE_HAS_TIMED_MESSAGE_BLOCKS"这个宏,所以 msg_deadline_time 和 msg_execution_time都不起任何作用.ACE_Message_Queue_Factory这个工•提供三个静态函数分别用来创建静态消息队列 和两种类型的动态消息队列。静态消息队列的消息也支持优先级,但是消息的优先级是静态 的,不需要通过动态计算而来。水位用来控制消息队列中数据的大小,高水位 (high_water_mark)用于控制消息队列的上限,它用于控制生产者往里面放数据的量, 如果消息队列中数据S:已经达到高水位,而用使用了锁,既使''ACE_Message_Queue_Factory<ACE_MT_SYNCH>: :create_static_message_queue();〃创建消息队列,那么生产者将被阻塞。高水位很容易理解,但是低水位是用来做什么的呢? 只要消息队列中还有数据消费者就不会被阻塞的,而当数据量超过高水位时,生产者会被阻 塞,既然会被阻塞,那么它肯定需要被唤醒,那么什么时候由谁来唤醒生产者呢?这就是低 水位的作用,消费者一直消费数据,当数据低于低水位时它就唤醒生产者。 下而的代码很好的展示了静态消息队列的使用。#include "ace/Message—Queue.h"#include "ace/Get_Opt.h"#include "ace/OS.h"#include <ace/Thread_Manager.h>#include <ace/Synch.h>//消息队列指针ACE_Message_Queue<ACE_MT_SYNCH>* mq;const char Sl[] = "C++"; const char S2[] = "Java"; const char S3[] = "PHP"; const char S4[] = "C#";//四个消息指针ACE一Message一Block* mbl, * mb2, * mb3, * mb4;//生产者static void* produce(void *arg){static int loop = 1; while(true){ACE_0S::sleep(2);ACE_DEBUG((LM_DEBUG/ "(%P : %t) producer…\n")); while(true){if(loop == 1){ //将高水位设置为10,S1+S2的长度为3+4+2=9<10,因此可以将S3放进去//但是再放入S4时生产者将会被阻塞//需要注意的是水位的大小并不是消息的个数,而是消息队列中消息里面的数据最之和 //如果也能以消息的个数作为高低水位的值就好了 mq->high_water_mark(10);mq->enqueue_prio (mbl); mq->enqueue_prio (mb2); mq->enqueue一prio (mb3);ACE_DEBUG((LM_DEBUG, "(%P : %t) producer will pending!!\n"));//因为消费者在睡眠6秒之后才会调用deactivate,因此生产者会在这儿阻塞儿秒钟 //可以不断地将msg_bytes打印出来观察观察 int ret = mq->enqueue一prio (mb4);ACE一DEBUG((LM_DEBUG, "(%P : %t) producer waken up by deactivate, ret = %d!!\n ret));++loop;>if(loop == 2){ACE一 0S::sleep(6);//将低水位设置为5,因为高水位仍然为10,3前的数据景乂超过了 10,//所以下面的入队操作仍会将生产者阻塞 //这样消费者消费消息,当数据景小于5时,将唤醒生产者 //生产者在此处等待被消费者唤醒 mq->low_water_mark(5);ACE一DEBUG((LM_DEBUG, "(%P : %t) producer will pending again!!\n")); mq->enqueue_prio (mb4);ACE一DEBUG((LM_DEBUG, "(%P : %t) producer waken up by consumer!!\n")); ++loop;>return NULL; >//消费者void* consume(void *arg){static int loop = 1; while(true){ACE_OS::sleep(2);ACE_DEBUG((LM_DEBUG, "(%P : %t) consumer...\n")); if(loop == 1)//等待6秒,此时生产者和消费者都将被阻塞 ACE—OS: :sleep(6);//deactivate会唤醒所有的线程,将消息队列设置为不可用 //以后所存取操作都会返回-1 //这个操作会唤醒生产者 mq->deactivate();++loop;>if(loop == 2){ACE_OS::sleep(2);//将消息队列的状态设置成ACTIVATED //消息乂可以使用了 mq->activate();++loop;>if(loop == 3){ACE一 OS: :sleep(10);//消费两个消息之后,数据罱就小于5 /,低于低水位将唤醒生产者 ACE一Message一Block *mb; mq->dequeue一head (mb); mq->dequeue_head (mb);ACE一DEBUG((LM_DEBUG, "(%P : %t) consumer wake up producer! !\n"));++loop;>return NULL;>int majn(int argc, char* argv[]){mq = ACE 一 Message 一 Queue_Factory<ACE_MT一 SYNCH〉: : create 一 static一 message—queue() int priority;//使用随机数作为消息的优先级//数字越高,优先级越岛’priority = ACE_OS: :rand() % 100;mbl = new ACE_Message__Block(Sl, sizeof SI, priority);priority = ACE_OS: :rand() % 100;mb2 = new ACE—Message一Block(S2, sizeof S2, priority);priority = ACE一OS::rand() % 100;mb3 = new ACE—Message一Block(S3, sizeof S3, priority);priority = ACE一OS::rand() % 100;mb4 = new ACE—Message一Block(S4, sizeof S4, priority);//将消息压入队列中,enqueue_prio根据消息的优先级将消息放到适3的位置上//enqueue_head只是简单地将数据存入队列中,而不考虑消息的优先级//使用 enqueue_prio 入消息后,可以简单通过 dequeue_head 和 dequeue_tail//分别按优先级从®到低和从低到高取消息//如果使用enqueue_head和enqueue_tail压入消息//则需要通过dequeue一prio来按照消息的优先级依次将消息出队列//没有必要既使用enqueue_prio压入消息,乂实用dequeue_prio来取消息mq->enqueue_prio (mbl);mq->enqueue_prio (mb2);mq->enqueue一prio (mb3);mq->enqueue_prio (mb4);//输出静态消息队列的相关信息//高低水位默认值均为16384ACE一DEBUG((LM_DEBUG, "count : %d, bytes : %d, length : %d, high一water一mark : %d low_water_mark : %d, status : %d\n",mq->message一count(), mq->message一bytes(), mq->message」ength(),mq->high一water一mark(), mq->low一water一mark(),mq->state()));ACE__Message一Block *mb;//使用next遍历消息,遍历的顺序为高优先级到底优先级ACE_DEBUG((LM_DEBUG, "= = = = = === = = = next= = = = = = = = = = = = =\n"));//peek—下,并不弹出消息,类似Windows的PeekMessage mq->peek一 dequeue 一 head(mb); do {ACE一DEBUG((LM_DEBUG, "message: %s, priority: %d\n", mb->rd_ptr()/ mb->msg_priority()));>while(mb = mb->next());//使用迭代器遍历消息队列,遍历的顺序为高优先级到底优先级ACE_DEBUG((LM一DEBUG, "= = = = = ====iterator= = = = = = = = = ====\n"));ACE—Message一Queue<ACE—MT一SYNCH>::ITERATOR iterator (*mq);for (ACE_Message_Block *entry = 0; iterator.next (entry) != 0; iterator.advance ()){ACE一DEBUG((LM_DEBUG, "message:。/。三,priority: %d\n", entry->rd_ptr(), entry->msg_priority()));>ACE一DEBUG((LM_DEBUG, "= = = = = = = = ====dequeue_head= = = = = === = =\n")); while(mq->dequeue_head (mb) != -1)ACE一DEBUG((LM_DEBUG, "message: %s, priority: %d\n", mb->rd_ptr(), mb->msg_priority()));//这里如果不判断的话,消息队列空时会导致主线程被阻塞if(mq->is 一 empty())break;>ACE一DEBUG((LM_DEBUG, "\n\n"));///AY////////////////////////////测试高低水位和队列的state使用,进行测试之前mq队列已空 /////////////////////////////产生一个生产者线程ACE—Thread—Manager::instance()->spawn__n ((ACE一THR一FUNC) produce );////产生两个消费者线程ACE 一Thread—Manager:: instance()->spawn_n ((ACE一THR一FUNC) consume );//挂起主线程ACE 一Thread—Manager: :instance()->wait(); return 0;>


0 0
原创粉丝点击