#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);
}