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及相关数据的代码:
ACE_Task::putq (ACE_Message_Block *mb, ACE_Time_Value *tv) {
ACE_TRACE ("ACE_Task::putq"); return this->msg_queue_->enqueue_tail (mb, tv); //直接添加到队列
}
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); //添加新数据块
...
}
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) //等侍队列有数据块弹出
{
...
}
...
}
...
}
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;
}
阅读(2356) | 评论(0) | 转发(0) |