peakzhang 发表于 2007-12-24 23:14:53

如何给线程池中的线程广播一个消息?

如何发送一个消息,使ACE_Task<ACE_MT_SYNCH>创建的线程池中的每个线程都可以收到该消息?达到类似广播的效果?
现在我在程序中往线程池发个消息,只要线程池中的一个线程用getq函数收到消息后,不管收到的消息有没有调用release(),线程池中其他线程都收不到这个消息了。

peakzhang 发表于 2007-12-24 23:15:00

办法其实很简单,你的一个线程svc函数中,收到退出消息后,自己退出之前,再把这个消息推入队列,让其它线程也收到。
int svc()
{
       if (message->msg_type () == ACE_Message_Block::MB_HANGUP)
          {
            if (this->putq (message) == -1)
            {
                ACE_ERROR ((LM_ERROR,
                            ACE_TEXT ("%p\n"),
                            ACE_TEXT ("Task::svc() putq")));
                message->release ();
            }
            break;
          }

}

peakzhang 发表于 2007-12-24 23:15:09

谢谢winston:

我在消息里保存了要关闭的线程ID,消息类型为:MB_STOP,想让指定的线程收到该消息,按您上面说得方法把消息重新推入队列,是关闭所有线程。但是如果putq()之后不关闭本线程(没有break语句),其他的线程还是收不到这个消息,一直都是他自己收的,其他线程怎么不能收呢?

代码如下, 帮忙看下好么?

int svc(void)
{
    while(1)
   {
       ACE_Message_Block *mb = NULL;
       if(this->getq(mb) == -1)
       {
            ACE_OS::sleep(wait_time);
            continue;
       }

      // 关闭指定的线程
      if(mb->msg_type() == ACE_Message_Block::MB_STOP)
      {
          ACE_thread_t thrd_id;
          memcpy(&thrd_id, mb, sizeof(ACE_thread_t));

       log_printf("CTask_Worker: [%d] get stop message [%d].\n", ACE_OS::thr_self(), thrd_id);

    if(ACE_OS::thr_equal(ACE_OS::thr_self(), thrd_id))
    {
   mb->release();
   break;
    }

   else
    {      

      if (this->putq (mb) == -1)
      {
         ACE_ERROR ((LM_ERROR,
         ACE_TEXT ("%p\n"),
          ACE_TEXT ("Task::svc() putq")));
         mb->release ();
       }
   }

    }

    return 0;
}

peakzhang 发表于 2007-12-24 23:15:17

在putq()成功之后,延迟了一段时间,这样其他线程就能收到,收到的线程跟延迟时间有关,时间短的话,只有某几个线程会收到,有些还是不能收到.

peakzhang 发表于 2007-12-24 23:15:24

这是操作系统的特性呀,你无从得知哪个线程被调度的。要进行等待,而不是随机延时,除非延时的时间够长。

peakzhang 发表于 2007-12-24 23:15:30

比较笨的办法,就是重新putq进入这个消息,然后自己等待,如Sleep(500),等待其它线程调用。
页: [1]
查看完整版本: 如何给线程池中的线程广播一个消息?