ACE的线程创建

本文详细介绍了如何使用ACE(AdvancedC++EmbeddableFramework)库中的Task和Thread_Manager类来创建线程池,包括Task类的open,close,svc方法以及Thread_Manager的spawn_n函数,展示了如何使用ACE的消息队列机制进行任务调度。
摘要由CSDN通过智能技术生成

#include "ace/Log_Msg.h"
#include "ace/OS.h"
#include "ace/Task.h"

#pragma comment(lib,"ace.lib")

class TaskOne :public ACE_Task<ACE_MT_SYNCH>
{
public:
    int open(void*)
    {
        ACE_DEBUG((LM_DEBUG, "(%t) active object task open()\n"));
        activate();/*默认创建一个线程*/
        return 0;
    }
    int close(u_long)
    {
        ACE_DEBUG((LM_DEBUG, "(%t) active object down\n"));
        return 0;
    }
    int svc(void)
    {
        ACE_DEBUG((LM_DEBUG, "(%t) Active object begin\n"));
        /*do what you want to do */
        return 0;
    }
};


int ACE_TMAIN(int argc, ACE_TCHAR* argv[])
{
    TaskOne* task = new TaskOne;

    task->open(0);

    ACE_Thread_Manager::instance()->wait();
    ACE_DEBUG((LM_DEBUG, "(%t) Main Task end\n"));

    return 0;
}

输出如下:

源码查看如下:

1)Task.cpp ACE_Task_Base::activate 函数定义如下:

int
ACE_Task_Base::activate (long flags,
                         int n_threads,
                         int force_active,
                         long priority,
                         int grp_id,
                         ACE_Task_Base *task,
                         ACE_hthread_t thread_handles[],
                         void *stack[],
                         size_t stack_size[],
                         ACE_thread_t thread_ids[],
                         const char* thr_name[])
{
  ACE_TRACE ("ACE_Task_Base::activate");

#if defined (ACE_MT_SAFE) && (ACE_MT_SAFE != 0)
  ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1);

  // If the task passed in is zero, we will use <this>
  if (task == 0)
    task = this;

  if (this->thr_count_ > 0 && force_active == 0)
    return 1; // Already active.
  else
    {
      if ((this->thr_count_ > 0 || grp_id == -1) &&
            this->grp_id_ != -1)
        // If we're joining an existing group of threads then make
        // sure to (re)use its group id.
        grp_id = this->grp_id_;
      else if (grp_id != -1)
        // make sure to reset the cached grp_id
        this->grp_id_ = -1;
      this->thr_count_ += n_threads;
    }

  // Use the ACE_Thread_Manager singleton if we're running as an
  // active object and the caller didn't supply us with a
  // Thread_Manager.
  if (this->thr_mgr_ == 0)
# if defined (ACE_THREAD_MANAGER_LACKS_STATICS)
    this->thr_mgr_ = ACE_THREAD_MANAGER_SINGLETON::instance ();
# else /* ! ACE_THREAD_MANAGER_LACKS_STATICS */
    this->thr_mgr_ = ACE_Thread_Manager::instance ();
# endif /* ACE_THREAD_MANAGER_LACKS_STATICS */

  int grp_spawned = -1;
  if (thread_ids == 0)
    // Thread Ids were not specified
    grp_spawned =
      this->thr_mgr_->spawn_n (n_threads,
                               &ACE_Task_Base::svc_run,
                               (void *) this,
                               flags,
                               priority,
                               grp_id,
                               task,
                               thread_handles,
                               stack,
                               stack_size,
                               thr_name);
  else
    // thread names were specified
    grp_spawned =
      this->thr_mgr_->spawn_n (thread_ids,
                               n_threads,
                               &ACE_Task_Base::svc_run, 
                               (void *) this,
                               flags,
                               priority,
                               grp_id,
                               stack,
                               stack_size,
                               thread_handles,
                               task,
                               thr_name);
  if (grp_spawned == -1)
    {
      // If spawn_n fails, restore original thread count.
      this->thr_count_ -= n_threads;
      return -1;
    }

  if (this->grp_id_ == -1)
    this->grp_id_ = grp_spawned;

#if defined(ACE_TANDEM_T1248_PTHREADS) || defined (ACE_THREAD_T_IS_A_STRUCT)
  ACE_OS::memcpy( &this->last_thread_id_, '\0', sizeof(this->last_thread_id_));
#else
  this->last_thread_id_ = 0;    // Reset to prevent inadvertant match on ID
#endif /* ACE_TANDEM_T1248_PTHREADS || ACE_THREAD_T_IS_A_STRUCT */

  return 0;

#else
  {
    // Keep the compiler from complaining.
    ACE_UNUSED_ARG (flags);
    ACE_UNUSED_ARG (n_threads);
    ACE_UNUSED_ARG (force_active);
    ACE_UNUSED_ARG (priority);
    ACE_UNUSED_ARG (grp_id);
    ACE_UNUSED_ARG (task);
    ACE_UNUSED_ARG (thread_handles);
    ACE_UNUSED_ARG (stack);
    ACE_UNUSED_ARG (stack_size);
    ACE_UNUSED_ARG (thread_ids);
    ACE_UNUSED_ARG (thr_name);
    ACE_NOTSUP_RETURN (-1);
  }
#endif /* ACE_MT_SAFE */
}

2)Thread_Manager.cpp ACE_Thread_Manager::spawn_n 函数定义如下:

/ Create N new threads running FUNC.

int
ACE_Thread_Manager::spawn_n (size_t n,
                             ACE_THR_FUNC func,
                             void *args,
                             long flags,
                             long priority,
                             int grp_id,
                             ACE_Task_Base *task,
                             ACE_hthread_t thread_handles[],
                             void *stack[],
                             size_t stack_size[],
                             const char* thr_name[])
{
  ACE_TRACE ("ACE_Thread_Manager::spawn_n");
  ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1));

  if (grp_id == -1)
    grp_id = this->grp_id_++; // Increment the group id.

  for (size_t i = 0; i < n; i++)
    {
      // @@ What should happen if this fails?! e.g., should we try to
      // cancel the other threads that we've already spawned or what?
      if (this->spawn_i (func,
                         args,
                         flags,
                         0,
                         thread_handles == 0 ? 0 : &thread_handles[i],
                         priority,
                         grp_id,
                         stack == 0 ? 0 : stack[i],
                         stack_size == 0 ? ACE_DEFAULT_THREAD_STACKSIZE : stack_size[i],
                         task,
                         thr_name == 0 ? 0 : &thr_name [i]) == -1)
        return -1;
    }

  return grp_id;
}

// Create N new threads running FUNC.

int
ACE_Thread_Manager::spawn_n (ACE_thread_t thread_ids[],
                             size_t n,
                             ACE_THR_FUNC func,
                             void *args,
                             long flags,
                             long priority,
                             int grp_id,
                             void *stack[],
                             size_t stack_size[],
                             ACE_hthread_t thread_handles[],
                             ACE_Task_Base *task,
                             const char* thr_name[])
{
  ACE_TRACE ("ACE_Thread_Manager::spawn_n");
  ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1));

  if (grp_id == -1)
    grp_id = this->grp_id_++; // Increment the group id.

  for (size_t i = 0; i < n; i++)
    {
      // @@ What should happen if this fails?! e.g., should we try to
      // cancel the other threads that we've already spawned or what?
      if (this->spawn_i (func,
                         args,
                         flags,
                         thread_ids == 0 ? 0 : &thread_ids[i],
                         thread_handles == 0 ? 0 : &thread_handles[i],
                         priority,
                         grp_id,
                         stack == 0 ? 0 : stack[i],
                         stack_size == 0 ? ACE_DEFAULT_THREAD_STACKSIZE : stack_size[i],
                         task,
                         thr_name == 0 ? 0 : &thr_name [i]) == -1)
        return -1;
    }

  return grp_id;
}

3)Task.cpp 文件,ACE_Task_Base::svc_run 如下:

ACE_THR_FUNC_RETURN
ACE_Task_Base::svc_run (void *args)
{
  ACE_TRACE ("ACE_Task_Base::svc_run");

  ACE_Task_Base *t = (ACE_Task_Base *) args;

  // Register ourself with our <Thread_Manager>'s thread exit hook
  // mechanism so that our close() hook will be sure to get invoked
  // when this thread exits.

#if defined ACE_HAS_SIG_C_FUNC
  t->thr_mgr ()->at_exit (t, ACE_Task_Base_cleanup, 0);
#else
  t->thr_mgr ()->at_exit (t, ACE_Task_Base::cleanup, 0);
#endif /* ACE_HAS_SIG_C_FUNC */

  ACE_THR_FUNC_RETURN status;
  // Call the Task's svc() hook method.
  int const svc_status = t->svc ();    //子类重写svc方法

#if defined (ACE_HAS_INTEGRAL_TYPE_THR_FUNC_RETURN)
  // Reinterpret case between integral types is not mentioned in the C++ spec
  status = static_cast<ACE_THR_FUNC_RETURN> (svc_status);
#else
  status = reinterpret_cast<ACE_THR_FUNC_RETURN> (svc_status);
#endif /* ACE_HAS_INTEGRAL_TYPE_THR_FUNC_RETURN */

// If we changed this zero change the other if in OS.cpp Thread_Adapter::invoke
#if 1
  // Call the <Task->close> hook.
  ACE_Thread_Manager *thr_mgr_ptr = t->thr_mgr ();

  // This calls the Task->close () hook.
  t->cleanup (t, 0);

  // This prevents a second invocation of the cleanup code
  // (called later by <ACE_Thread_Manager::exit>.
  thr_mgr_ptr->at_exit (t, 0, 0);
#endif
  return status;
}

4)Task.cpp 文件,ACE_Task_Base::svc 如下:

/// Default ACE_Task service routine
int
ACE_Task_Base::svc (void)
{
  ACE_TRACE ("ACE_Task_Base::svc");
  return 0;
}

Task.h文件:

  /// Run by a daemon thread to handle deferred processing.
  virtual int svc (void);

具体的我们在外部重写的虚函数svc函数执行。

Task_T.inl 文件中getq和putq实现如下:

template <ACE_SYNCH_DECL, class TIME_POLICY> ACE_INLINE int
ACE_Task<ACE_SYNCH_USE, TIME_POLICY>::getq (ACE_Message_Block *&mb, ACE_Time_Value *tv)
{
  ACE_TRACE ("ACE_Task<ACE_SYNCH_USE, TIME_POLICY>::getq");
  return this->msg_queue_->dequeue_head (mb, tv);
}

template <ACE_SYNCH_DECL, class TIME_POLICY> ACE_INLINE int
ACE_Task<ACE_SYNCH_USE, TIME_POLICY>::putq (ACE_Message_Block *mb, ACE_Time_Value *tv)
{
  ACE_TRACE ("ACE_Task<ACE_SYNCH_USE, TIME_POLICY>::putq");
  return this->msg_queue_->enqueue_tail (mb, tv);
}

https://www.cnblogs.com/binchen-china/p/5614275.html

基于ACE应用编程框架——线程池_ace_message_block::mb_hangup-CSDN博客

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值