Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1687956
  • 博文数量: 347
  • 博客积分: 9328
  • 博客等级: 中将
  • 技术积分: 2680
  • 用 户 组: 普通用户
  • 注册时间: 2010-07-29 23:45
文章分类

全部博文(347)

文章存档

2016年(1)

2013年(4)

2012年(207)

2011年(85)

2010年(50)

分类: C/C++

2012-08-24 17:33:47

int ACE_Task< ACE_SYNCH_DECL >::putq (     ACE_Message_Block * , ACE_Time_Value *     timeout = 0    )     

提供了一个向线程中提交数据的方法

它是通过将提交数据插入到线程的消息队列来(msg_queue)完成这个操作的,我起初认为这个方法是完全异步的,也就是说调用时不会阻塞,但最近在使用线程池时,发现,如果msg_queue已满,则会阻塞,阻塞时时间长度,由putq的第二个参数来决定。
调用putq时,向msg_queue添加数据(enqueue_tail),而在线程中,getq时,从队列中弹出(dequeue_head),每次调用enqueue_tail时,msg_queue都方法:is_full_i()来判断队列是否已满,在is_full_i()中,是通过判断队列中所有数据块的总长度来确定是否已满的,而不是通过数据块个数:this->cur_bytes_ >= this->high_water_mark_

以下为putq及相关数据的代码:
template ACE_INLINE int
ACE_Task::putq (ACE_Message_Block *mb, ACE_Time_Value *tv)
{
ACE_TRACE ("ACE_Task::putq");
return this->msg_queue_->enqueue_tail (mb, tv); //直接添加到队列
}



template int
ACE_Message_Queue::enqueue_tail (ACE_Message_Block *new_item,
                                              ACE_Time_Value *timeout)
{
   ...

    if (this->wait_not_full_cond (ace_mon, timeout) == -1) //检测并确保队列未满
      return -1;

    queue_count = this->enqueue_tail_i (new_item); //添加新数据块
...

}



template int
ACE_Message_Queue::wait_not_full_cond (ACE_Guard &,
                                                      ACE_Time_Value *timeout)
{
...
while (this->is_full_i ()) //决断队列是否已满
    {
      if (this->not_full_cond_.wait (timeout) == -1) //等侍队列有数据块弹出
        {
...
        }
...
    }
...
}


template int
ACE_Message_Queue::is_full_i (void)
{
ACE_TRACE ("ACE_Message_Queue::is_full_i");
return this->cur_bytes_ >= this->high_water_mark_; //cur_bytes的值在是所有数据块长度的和, high_water_mark_的默认值为:0x4000,可以在能过方法high_water_mark()来修改,在ACE_Message_Queue::open时,可以通过参数指定.
}



使用注意事项:
http://blog.csdn.net/hxzb7215191/article/details/800018 
在使用ACE_Task的时候,可以把这个对象看成一个处理器对象,他有一个消息队列,有一堆的线程在处理这一个消息。所以在应用中使用这个东西的机会特别的多。这次我使用的时候发现一个这样的问题。如果数据的速度太快了的时候将会使调用putq函数调用不成功。
这是一个例子代码,其实每一个Task都聚集了一个msg_queue对象的指针,他有一个参数:high_water_mark,就是说,在这个队列中的每个元素的size之和的最高。他的默认值是1024*16。但是有可能还是被占满了。如果发现putq不成功的时候就要使用这个东西来调整水位了。

int ACE_TMAIN(int, ACE_TCHAR *[])
{
 MyTask task;
 task.star();
 task.msg_queue_->high_water_mark(16385);
 ACE_Message_Block *new1=new ACE_Message_Block(16384);
 task.putq(new1);
 new1=new ACE_Message_Block(1);
 ACE_Time_Value tv(0,1000);

 if (task.putq(new1,&tv)==-1)
 {
  cout<<"put时失败"<
 }
 getchar();
 return 0;
}
阅读(2305) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~