winston 发表于 2012-2-29 00:28:27

ACE_Thread_Manager-------ACE线程管理

在一个ACE项目中使用线程是再常见不过了。然而ACE线程做到了很好的管理。使用了ACE_Thread_Manager封装了很多东西。
该类是将启动的线程放到了一个双向链表里进行管理的。

当我们想启动一个线程的时候,我们就可以这样的使用
启动线程:
view plaincopyprint?


[*]void* func(void*);
[*]
[*]ACE_Thread_Manager::instance()->spawn(ACE_THR_FUNC(func), 0, THR_NEW_LWP);

线程阻塞,等待子线程退出:
view plaincopyprint?


[*]ACE_Thread_Manager::instance()->wait();

ACE_Thread_Manager使用了单例模式。

ACE_Thread_Manager代码展示
带参构造函数
view plaincopyprint?


[*]ACE_Thread_Manager::ACE_Thread_Manager (size_t prealloc,
[*]                                        size_t lwm,
[*]                                        size_t inc,
[*]                                        size_t hwm)
[*]: grp_id_ (1),
[*]    automatic_wait_ (1)
[*]#if defined (ACE_HAS_THREADS)
[*]    , zero_cond_ (lock_)
[*]#endif /* ACE_HAS_THREADS */
[*]    , thread_desc_freelist_ (ACE_FREE_LIST_WITH_POOL,
[*]                           prealloc, lwm, hwm, inc)
[*]{
[*]ACE_TRACE ("ACE_Thread_Manager::ACE_Thread_Manager");
[*]}


单例模式函数:
其中他ACE_Thread_Manager::delete_thr_mgr_ 布尔变量,当实例化的时候,设置true。
view plaincopyprint?


[*]#if ! defined (ACE_THREAD_MANAGER_LACKS_STATICS)
[*]ACE_Thread_Manager *
[*]ACE_Thread_Manager::instance (void)
[*]{
[*]ACE_TRACE ("ACE_Thread_Manager::instance");
[*]
[*]if (ACE_Thread_Manager::thr_mgr_ == 0)
[*]    {
[*]      // Perform Double-Checked Locking Optimization.
[*]      ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon,
[*]                              *ACE_Static_Object_Lock::instance (), 0));
[*]
[*]      if (ACE_Thread_Manager::thr_mgr_ == 0)
[*]      {
[*]          ACE_NEW_RETURN (ACE_Thread_Manager::thr_mgr_,
[*]                        ACE_Thread_Manager,
[*]                        0);
[*]          ACE_Thread_Manager::delete_thr_mgr_ = true;
[*]      }
[*]    }
[*]
[*]return ACE_Thread_Manager::thr_mgr_;
[*]}
[*]
[*]ACE_Thread_Manager *
[*]ACE_Thread_Manager::instance (ACE_Thread_Manager *tm)
[*]{
[*]ACE_TRACE ("ACE_Thread_Manager::instance");
[*]ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon,
[*]                            *ACE_Static_Object_Lock::instance (), 0));
[*]
[*]ACE_Thread_Manager *t = ACE_Thread_Manager::thr_mgr_;
[*]// We can't safely delete it since we don't know who created it!
[*]ACE_Thread_Manager::delete_thr_mgr_ = false;
[*]
[*]ACE_Thread_Manager::thr_mgr_ = tm;
[*]return t;
[*]}


清除实例对象:
view plaincopyprint?


[*]void
[*]ACE_Thread_Manager::close_singleton (void)
[*]{
[*]ACE_TRACE ("ACE_Thread_Manager::close_singleton");
[*]
[*]ACE_MT (ACE_GUARD (ACE_Recursive_Thread_Mutex, ace_mon,
[*]                     *ACE_Static_Object_Lock::instance ()));
[*]
[*]if (ACE_Thread_Manager::delete_thr_mgr_)
[*]    {
[*]      // First, we clean up the thread descriptor list.
[*]      ACE_Thread_Manager::thr_mgr_->close ();
[*]      delete ACE_Thread_Manager::thr_mgr_;
[*]      ACE_Thread_Manager::thr_mgr_ = 0;
[*]      ACE_Thread_Manager::delete_thr_mgr_ = false;
[*]    }
[*]
[*]ACE_Thread_Exit::cleanup (ACE_Thread_Manager::thr_exit_);
[*]}


析构函数,清除对象:
view plaincopyprint?


[*]int
[*]ACE_Thread_Manager::close ()
[*]{
[*]ACE_TRACE ("ACE_Thread_Manager::close");
[*]
[*]// Clean up the thread descriptor list.
[*]if (this->automatic_wait_)
[*]    this->wait (0, 1);
[*]else
[*]    {
[*]      ACE_MT (ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1));
[*]
[*]      this->remove_thr_all ();
[*]    }
[*]
[*]return 0;
[*]}
[*]
[*]ACE_Thread_Manager::~ACE_Thread_Manager (void)
[*]{
[*]ACE_TRACE ("ACE_Thread_Manager::~ACE_Thread_Manager");
[*]this->close ();
[*]}




[*]void
[*]ACE_Thread_Manager::remove_thr_all (void)
[*]{
[*]ACE_Thread_Descriptor *td = 0;
[*]
[*]while ((td = this->thr_list_.delete_head ()) != 0)
[*]    {
[*]      this->remove_thr (td, 1);
[*]    }
[*]}


线程启动函数:
view plaincopyprint?


[*]简单介绍一下参数:

简单介绍一下参数: view plaincopyprint?


[*]func:线程函数,不用多数

func:线程函数,不用多数 view plaincopyprint?


[*]args:线程函数参数,

args:线程函数参数, view plaincopyprint?


[*]flags:线程的属性控制Flags to control attributes of the spawned threads.
[*]   *                  @sa ACE_OS::thr_create() for descriptions of the
[*]   *                  possible flags values and their interactions.




[*]t_id:线程id

t_id:线程id view plaincopyprint?


[*]t_handle: Pointer to a location to receive the spawned thread's
[*]   *                  thread handle. If 0, the handle is not returned.




[*]priority:线程的优先级

priority:线程的优先级 view plaincopyprint?


[*]grp_id:组id




[*]stack:线程栈 stack_size:栈大小




[*]

view plaincopyprint?


[*]size_t n:启动几次线程




[*]int
[*]ACE_Thread_Manager::spawn (ACE_THR_FUNC func,
[*]                           void *args,
[*]                           long flags,
[*]                           ACE_thread_t *t_id,
[*]                           ACE_hthread_t *t_handle,
[*]                           long priority,
[*]                           int grp_id,
[*]                           void *stack,
[*]                           size_t stack_size,
[*]                           const char** thr_name)
[*]{
[*]ACE_TRACE ("ACE_Thread_Manager::spawn");
[*]
[*]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.
[*]
[*]if (priority != ACE_DEFAULT_THREAD_PRIORITY)
[*]    ACE_CLR_BITS (flags, THR_INHERIT_SCHED);
[*]
[*]if (this->spawn_i (func,
[*]                     args,
[*]                     flags,
[*]                     t_id,
[*]                     t_handle,
[*]                     priority,
[*]                     grp_id,
[*]                     stack,
[*]                     stack_size,
[*]                     0,
[*]                     thr_name) == -1)
[*]    return -1;
[*]
[*]return grp_id;
[*]}
[*]
[*]// 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,
[*]                         priority,
[*]                         grp_id,
[*]                         stack == 0 ? 0 : stack,
[*]                         stack_size == 0 ? ACE_DEFAULT_THREAD_STACKSIZE : stack_size,
[*]                         task,
[*]                         thr_name == 0 ? 0 : &thr_name ) == -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,
[*]                         thread_handles == 0 ? 0 : &thread_handles,
[*]                         priority,
[*]                         grp_id,
[*]                         stack == 0 ? 0 : stack,
[*]                         stack_size == 0 ? ACE_DEFAULT_THREAD_STACKSIZE : stack_size,
[*]                         task,
[*]                         thr_name == 0 ? 0 : &thr_name ) == -1)
[*]      return -1;
[*]    }
[*]
[*]return grp_id;
[*]}


下面是函数,更具其名字应该能知道线程管理的意义了:

view plaincopyprint?


[*] ACE_THR_FUNC_RETURN exit (ACE_THR_FUNC_RETURN status = 0,
[*]                            bool do_thread_exit = true);
[*]
[*]/**
[*]   * Block until there are no more threads running in this thread
[*]   * manager or @c timeout expires.
[*]   *
[*]   * @param timeout is treated as "absolute" time by default, but this
[*]   *                can be changed to "relative" time by setting the @c
[*]   *                use_absolute_time to false.
[*]   * @param abandon_detached_threads If true, @c wait() will first
[*]   *                                 check thru its thread list for
[*]   *                                 threads with THR_DETACHED or
[*]   *                                 THR_DAEMON flags set and remove
[*]   *                                 these threads.Notice that
[*]   *                                 unlike other @c wait_*() methods,
[*]   *                                 by default, @c wait() does wait on
[*]   *                                 all thread spawned by this
[*]   *                                 thread manager no matter the detached
[*]   *                                 flags are set or not unless it is
[*]   *                                 called with @c
[*]   *                                 abandon_detached_threads flag set.
[*]   * @param use_absolute_time If true then treat @c timeout as
[*]   *                        absolute time, else relative time.
[*]   * @return 0 on success * and -1 on failure.
[*]   *
[*]   * @note If this function is called while the @c
[*]   * ACE_Object_Manager is shutting down (as a result of program
[*]   * rundown via @c ACE::fini()), it will not wait for any threads to
[*]   * complete. If you must wait for threads spawned by this thread
[*]   * manager to complete and you are in a ACE rundown situation (such
[*]   * as your object is being destroyed by the @c ACE_Object_Manager)
[*]   * you can use @c wait_grp() instead.
[*]   */
[*]int wait (const ACE_Time_Value *timeout = 0,
[*]            bool abandon_detached_threads = false,
[*]            bool use_absolute_time = true);
[*]
[*]/// Join a thread specified by @a tid.Do not wait on a detached thread.   
[*]int join (ACE_thread_t tid, ACE_THR_FUNC_RETURN *status = 0);
[*]
[*]/**
[*]   * Block until there are no more threads running in a group.
[*]   * Returns 0 on success and -1 on failure.Notice that wait_grp
[*]   * will not wait on detached threads.
[*]   */
[*]int wait_grp (int grp_id);
[*]
[*]/**
[*]   * Return the "real" handle to the calling thread, caching it if
[*]   * necessary in TSS to speed up subsequent lookups. This is
[*]   * necessary since on some platforms (e.g., Windows) we can't get this
[*]   * handle via direct method calls.Notice that you should *not*
[*]   * close the handle passed back from this method.It is used
[*]   * internally by Thread Manager.On the other hand, you *have to*
[*]   * use this internal thread handle when working on Thread_Manager.
[*]   * Return -1 if fail.
[*]   */
[*]int thr_self (ACE_hthread_t &);
[*]
[*]/**
[*]   * Return the unique ID of the calling thread.
[*]   * Same as calling ACE_Thread::self().
[*]   */
[*]ACE_thread_t thr_self (void);
[*]
[*]/**
[*]   * Returns a pointer to the current ACE_Task_Base we're executing
[*]   * in if this thread is indeed running in an ACE_Task_Base, else
[*]   * return 0.
[*]   */
[*]ACE_Task_Base *task (void);
[*]
[*]/**
[*]   * @name Suspend and resume methods
[*]   *
[*]   * Suspend/resume is not supported on all platforms. For example, Pthreads
[*]   * does not support these functions.
[*]   */
[*]//@{   
[*]
[*]/// Suspend all threads   
[*]int suspend_all (void);
[*]
[*]/// Suspend a single thread.   
[*]int suspend (ACE_thread_t);
[*]
[*]/// Suspend a group of threads.   
[*]int suspend_grp (int grp_id);
[*]
[*]/**
[*]   * True if @a t_id is inactive (i.e., suspended), else false.Always
[*]   * return false if @a t_id is not managed by the Thread_Manager.
[*]   */
[*]int testsuspend (ACE_thread_t t_id);
[*]
[*]/// Resume all stopped threads   
[*]int resume_all (void);
[*]
[*]/// Resume a single thread.   
[*]int resume (ACE_thread_t);
[*]
[*]/// Resume a group of threads.   
[*]int resume_grp (int grp_id);
[*]
[*]/**
[*]   * True if @a t_id is active (i.e., resumed), else false.Always
[*]   * return false if @a t_id is not managed by the Thread_Manager.
[*]   */
[*]int testresume (ACE_thread_t t_id);
[*]
[*]//@}   
[*]
[*]// = Send signals to one or more threads without blocking.   
[*]/**
[*]   * Send @a signum to all stopped threads.Not supported on platforms
[*]   * that do not have advanced signal support, such as Win32.
[*]   */
[*]int kill_all (int signum);
[*]/**
[*]   * Send the @a signum to a single thread.Not supported on platforms
[*]   * that do not have advanced signal support, such as Win32.
[*]   */
[*]int kill (ACE_thread_t, int signum);
[*]/**
[*]   * Send @a signum to a group of threads, not supported on platforms
[*]   * that do not have advanced signal support, such as Win32.
[*]   */
[*]int kill_grp (int grp_id, int signum);
[*]
[*]// = Cancel methods, which provides a cooperative thread-termination mechanism (will not block).   
[*]/**
[*]   * Cancel's all the threads.
[*]   */
[*]int cancel_all (int async_cancel = 0);
[*]
[*]/**
[*]   * Cancel a single thread.
[*]   */
[*]int cancel (ACE_thread_t, int async_cancel = 0);
[*]
[*]/**
[*]   * Cancel a group of threads.
[*]   */
[*]int cancel_grp (int grp_id, int async_cancel = 0);
[*]
[*]/**
[*]   * True if @a t_id is cancelled, else false.Always return false if
[*]   * @a t_id is not managed by the Thread_Manager.
[*]   */
[*]int testcancel (ACE_thread_t t_id);
[*]
[*]/**
[*]   * True if @a t_id has terminated (i.e., is no longer running),
[*]   * but the slot in the thread manager hasn't been reclaimed yet,
[*]   * else false.Always return false if @a t_id is not managed by the
[*]   * Thread_Manager.
[*]   */
[*]int testterminate (ACE_thread_t t_id);
[*]
[*]/// Set group ids for a particular thread id.   
[*]int set_grp (ACE_thread_t,
[*]               int grp_id);
[*]
[*]/// Get group ids for a particular thread id.   
[*]int get_grp (ACE_thread_t,
[*]               int &grp_id);
[*]
[*]/**
[*]   * @name Task-related operations
[*]   */
[*]//@{   
[*]/**
[*]   * Block until there are no more threads running in a specified task.
[*]   * This method will not wait for either detached or daemon threads;
[*]   * the threads must have been spawned with the @c THR_JOINABLE flag.
[*]   * Upon successful completion, the threads have been joined, so further
[*]   * attempts to join with any of the waited-for threads will fail.
[*]   *
[*]   * @param taskThe ACE_Task_Base object whose threads are to waited for.
[*]   *
[*]   * @retval 0Success.
[*]   * @retval -1 Failure (consult errno for further information).
[*]   */
[*]int wait_task (ACE_Task_Base *task);
[*]
[*]/**
[*]   * Suspend all threads in an ACE_Task.
[*]   */
[*]int suspend_task (ACE_Task_Base *task);
[*]
[*]/**
[*]   * Resume all threads in an ACE_Task.
[*]   */
[*]int resume_task (ACE_Task_Base *task);
[*]
[*]/**
[*]   * Send a signal @a signum to all threads in an ACE_Task.
[*]   */
[*]int kill_task (ACE_Task_Base *task, int signum);
[*]
[*]/**
[*]   * Cancel all threads in an ACE_Task.If <async_cancel> is non-0,
[*]   * then asynchronously cancel these threads if the OS platform
[*]   * supports cancellation.Otherwise, perform a "cooperative"
[*]   * cancellation.
[*]   */
[*]int cancel_task (ACE_Task_Base *task, int async_cancel = 0);
[*]
[*]//@}   
[*]
[*]// = Collect thread handles in the thread manager.Notice that   
[*]//   the collected information is just a snapshot.   
[*]/// Check if the thread is managed by the thread manager.Return true if   
[*]/// the thread is found, false otherwise.   
[*]int hthread_within (ACE_hthread_t handle);
[*]int thread_within (ACE_thread_t tid);
[*]
[*]/// Returns the number of ACE_Task_Base in a group.   
[*]int num_tasks_in_group (int grp_id);
[*]
[*]/// Returns the number of threads in an ACE_Task_Base.   
[*]int num_threads_in_task (ACE_Task_Base *task);
[*]
[*]/**
[*]   * Returns a list of ACE_Task_Base pointers corresponding to the tasks
[*]   * that have active threads in a specified thread group.
[*]   *
[*]   * @param grp_id    The thread group ID to obtain task pointers for.
[*]   *
[*]   * @param task_list is a pointer to an array to receive the list of pointers.
[*]   *                  The caller is responsible for supplying an array with at
[*]   *                  least @arg n entries.
[*]   *
[*]   * @param n         The maximum number of ACE_Task_Base pointers to write
[*]   *                  in @arg task_list.
[*]   *
[*]   * @retvalIf successful, the number of pointers returned, which will be
[*]   *          no greater than @arg n. Returns -1 on error.
[*]   *
[*]   * @note    This method has no way to indicate if there are more than
[*]   *          @arg n ACE_Task_Base pointers available. Therefore, it may be
[*]   *          wise to guess a larger value of @arg n than one thinks in cases
[*]   *          where the exact number of tasks is not known.
[*]   *
[*]   * @sa      num_tasks_in_group(), task_all_list()
[*]   */
[*]ssize_t task_list (int grp_id,
[*]                     ACE_Task_Base *task_list[],
[*]                     size_t n);
[*]
[*]/**
[*]   * Returns in @a thread_list a list of up to @a n thread ids in an
[*]   * ACE_Task_Base.The caller must allocate the memory for
[*]   * @a thread_list.In case of an error, -1 is returned. If no
[*]   * requested values are found, 0 is returned, otherwise correct
[*]   * number of retrieved values are returned.
[*]   */
[*]ssize_t thread_list (ACE_Task_Base *task,
[*]                     ACE_thread_t thread_list[],
[*]                     size_t n);
[*]
[*]/**
[*]   * Returns in @a hthread_list a list of up to @a n thread handles in
[*]   * an ACE_Task_Base.The caller must allocate memory for
[*]   * @a hthread_list.In case of an error, -1 is returned. If no
[*]   * requested values are found, 0 is returned, otherwise correct
[*]   * number of retrieved values are returned.
[*]   */
[*]ssize_t hthread_list (ACE_Task_Base *task,
[*]                        ACE_hthread_t hthread_list[],
[*]                        size_t n);
[*]
[*]/**
[*]   * Returns in @a thread_list a list of up to @a n thread ids in a
[*]   * group @a grp_id.The caller must allocate the memory for
[*]   * @a thread_list.In case of an error, -1 is returned. If no
[*]   * requested values are found, 0 is returned, otherwise correct
[*]   * number of retrieved values are returned.
[*]   */
[*]ssize_t thread_grp_list (int grp_id,
[*]                           ACE_thread_t thread_list[],
[*]                           size_t n);
[*]
[*]/**
[*]   * Returns in @a hthread_list a list of up to @a n thread handles in
[*]   * a group @a grp_id.The caller must allocate memory for
[*]   * @a hthread_list.
[*]   */
[*]ssize_t hthread_grp_list (int grp_id,
[*]                            ACE_hthread_t hthread_list[],
[*]                            size_t n);
[*]
[*]/**
[*]   * Returns a list of ACE_Task_Base pointers corresponding to the tasks
[*]   * that have active threads managed by this instance.
[*]   *
[*]   * @param task_list is a pointer to an array to receive the list of pointers.
[*]   *                  The caller is responsible for supplying an array with at
[*]   *                  least @arg n entries.
[*]   *
[*]   * @param n         The maximum number of ACE_Task_Base pointers to write
[*]   *                  in @arg task_list.
[*]   *
[*]   * @retvalIf successful, the number of pointers returned, which will be
[*]   *          no greater than @arg n. Returns -1 on error.
[*]   *
[*]   * @note    This method has no way to indicate if there are more than
[*]   *          @arg n ACE_Task_Base pointers available. Therefore, it may be
[*]   *          wise to guess a larger value of @arg n than one thinks in cases
[*]   *          where the exact number of tasks is not known.
[*]   *
[*]   * @sa      count_threads()
[*]   */
[*]ssize_t task_all_list (ACE_Task_Base *task_list[],
[*]                         size_t n);
[*]
[*]/**
[*]   * Returns in @a thread_list a list of up to @a n thread ids.The
[*]   * caller must allocate the memory for @a thread_list.In case of an
[*]   * error, -1 is returned. If no requested values are found, 0 is
[*]   * returned, otherwise correct number of retrieved values are
[*]   * returned.
[*]   */
[*]ssize_t thread_all_list (ACE_thread_t thread_list[],
[*]                           size_t n);
[*]
[*]/// Set group ids for a particular task.   
[*]int set_grp (ACE_Task_Base *task, int grp_id);
[*]
[*]/// Get group ids for a particular task.   
[*]int get_grp (ACE_Task_Base *task, int &grp_id);
[*]
[*]/// Return a count of the current number of threads active in the   
[*]/// <Thread_Manager>.   
[*]size_t count_threads (void) const;
[*]
[*]/// Get the state of the thread. Returns false if the thread is not   
[*]/// managed by this thread manager.   
[*]int thr_state (ACE_thread_t id, ACE_UINT32& state);
[*]
[*]/**
[*]   * Register an At_Thread_Exit hook and the ownership is acquire by
[*]   * Thread_Descriptor, this is the usual case when the AT is dynamically
[*]   * allocated.
[*]   */
[*]int at_exit (ACE_At_Thread_Exit* cleanup);
[*]
[*]/// Register an At_Thread_Exit hook and the ownership is retained for the   
[*]/// caller. Normally used when the at_exit hook is created in stack.   
[*]int at_exit (ACE_At_Thread_Exit& cleanup);
[*]
[*]/**
[*]   *
[*]   *****
[*]   * @deprecated This function is deprecated.Please use the previous two
[*]   *    at_exit method.Notice that you should avoid mixing this method
[*]   *    with the previous two at_exit methods.
[*]   *****
[*]   *
[*]   * Register an object (or array) for cleanup at
[*]   * thread termination."cleanup_hook" points to a (global, or
[*]   * static member) function that is called for the object or array
[*]   * when it to be destroyed.It may perform any necessary cleanup
[*]   * specific for that object or its class."param" is passed as the
[*]   * second parameter to the "cleanup_hook" function; the first
[*]   * parameter is the object (or array) to be destroyed.
[*]   * "cleanup_hook", for example, may delete the object (or array).
[*]   * If <cleanup_hook> == 0, the <object> will _NOT_ get cleanup at
[*]   * thread exit.You can use this to cancel the previously added
[*]   * at_exit.
[*]   */
[*]int at_exit (void *object,
[*]               ACE_CLEANUP_FUNC cleanup_hook,
[*]               void *param);
[*]
[*]/// Access function to determine whether the Thread_Manager will   
[*]/// wait for its thread to exit or not when being closing down.   
[*]void wait_on_exit (int dowait);
[*]int wait_on_exit (void);
[*]
[*]/// Dump the state of an object.   
[*]void dump (void);
[*]
[*]/// Declare the dynamic allocation hooks.   
[*]ACE_ALLOC_HOOK_DECLARE;
[*]
[*]protected:
[*]// = Accessors for ACE_Thread_Descriptors.   
[*]/**
[*]   * Get a pointer to the calling thread's own thread_descriptor.
[*]   * This must be called from a spawn thread.This function will
[*]   * fetch the info from TSS.
[*]   */
[*]ACE_Thread_Descriptor *thread_desc_self (void);
[*]
[*]/// Return a pointer to the thread's Thread_Descriptor,   
[*]/// 0 if fail.   
[*]ACE_Thread_Descriptor *thread_descriptor (ACE_thread_t);
[*]
[*]/// Return a pointer to the thread's Thread_Descriptor,   
[*]/// 0 if fail.   
[*]ACE_Thread_Descriptor *hthread_descriptor (ACE_hthread_t);
[*]
[*]/// Create a new thread (must be called with locks held).   
[*]int spawn_i (ACE_THR_FUNC func,
[*]               void *arg,
[*]               long flags,
[*]               ACE_thread_t * = 0,
[*]               ACE_hthread_t *t_handle = 0,
[*]               long priority = ACE_DEFAULT_THREAD_PRIORITY,
[*]               int grp_id = -1,
[*]               void *stack = 0,
[*]               size_t stack_size = 0,
[*]               ACE_Task_Base *task = 0,
[*]               const char** thr_name = 0);
[*]
[*]/// Run the registered hooks when the thread exits.   
[*]void run_thread_exit_hooks (int i);
[*]
[*]/// Locate the index of the table slot occupied by <t_id>.Returns   
[*]/// -1 if <t_id> is not in the table doesn't contain <t_id>.   
[*]ACE_Thread_Descriptor *find_thread (ACE_thread_t t_id);
[*]
[*]/// Locate the index of the table slot occupied by <h_id>.Returns   
[*]/// -1 if <h_id> is not in the table doesn't contain <h_id>.   
[*]ACE_Thread_Descriptor *find_hthread (ACE_hthread_t h_id);
[*]
[*]/**
[*]   * Locate the thread descriptor address of the list occupied by
[*]   * @a task.Returns 0 if @a task is not in the table doesn't contain
[*]   * @a task.
[*]   */
[*]ACE_Thread_Descriptor *find_task (ACE_Task_Base *task,
[*]                                    size_t slot = 0);
[*]
[*]/// Insert a thread in the table (checks for duplicates).   
[*]int insert_thr (ACE_thread_t t_id,
[*]                  ACE_hthread_t,
[*]                  int grp_id = -1,
[*]                  long flags = 0);
[*]
[*]/// Append a thread in the table (adds at the end, growing the table   
[*]/// if necessary).   
[*]int append_thr (ACE_thread_t t_id, ACE_hthread_t,
[*]                  ACE_UINT32,
[*]                  int grp_id,
[*]                  ACE_Task_Base *task = 0,
[*]                  long flags = 0,
[*]                  ACE_Thread_Descriptor *td = 0);
[*]
[*]/// Remove thread from the table.   
[*]void remove_thr (ACE_Thread_Descriptor *td,
[*]                   int close_handler);
[*]
[*]/// Remove all threads from the table.   
[*]void remove_thr_all (void);
[*]
[*]// = The following four methods implement a simple scheme for   
[*]// operating on a collection of threads atomically.   
[*]
[*]/**
[*]   * Efficiently check whether @a thread is in a particular @a state.
[*]   * This call updates the TSS cache if possible to speed up
[*]   * subsequent searches.
[*]   */
[*]int check_state (ACE_UINT32 state,
[*]                   ACE_thread_t thread,
[*]                   int enable = 1);
[*]
[*]/// Apply @a func to all members of the table that match the @a task   
[*]int apply_task (ACE_Task_Base *task,
[*]                  ACE_THR_MEMBER_FUNC func,
[*]                  int = 0);
[*]
[*]/// Apply @a func to all members of the table that match the @a grp_id.   
[*]int apply_grp (int grp_id,
[*]               ACE_THR_MEMBER_FUNC func,
[*]               int arg = 0);
[*]
[*]/// Apply @a func to all members of the table.   
[*]int apply_all (ACE_THR_MEMBER_FUNC,
[*]               int= 0);
[*]
[*]/// Join the thread described in @a td.   
[*]int join_thr (ACE_Thread_Descriptor *td,
[*]                int = 0);
[*]
[*]/// Resume the thread described in @a td.   
[*]int resume_thr (ACE_Thread_Descriptor *td,
[*]                  int = 0);
[*]
[*]/// Suspend the thread described in @a td.   
[*]int suspend_thr (ACE_Thread_Descriptor *td,
[*]                   int = 0);
[*]
[*]/// Send signal @a signum to the thread described in @a td.   
[*]int kill_thr (ACE_Thread_Descriptor *td,
[*]                int signum);
[*]
[*]/// Set the cancellation flag for the thread described in @a td.   
[*]int cancel_thr (ACE_Thread_Descriptor *td,
[*]                  int async_cancel = 0);
[*]
[*]/// Register a thread as terminated and put it into the <terminated_thr_list_>.   
[*]int register_as_terminated (ACE_Thread_Descriptor *td);
[*]
[*]/// Setting the static ACE_TSS_TYPE (ACE_Thread_Exit) *thr_exit_ pointer.   
[*]static int set_thr_exit (ACE_TSS_TYPE (ACE_Thread_Exit) *ptr);
[*]
[*]/**
[*]   * Keeping a list of thread descriptors within the thread manager.
[*]   * Double-linked list enables us to cache the entries in TSS
[*]   * and adding/removing thread descriptor entries without
[*]   * affecting other thread's descriptor entries.
[*]   */
[*]ACE_Double_Linked_List<ACE_Thread_Descriptor> thr_list_;
[*]
[*]#if !defined (ACE_HAS_VXTHREADS)   
[*]/// Collect terminated but not yet joined thread entries.   
[*]ACE_Double_Linked_List<ACE_Thread_Descriptor_Base> terminated_thr_list_;
[*]#endif /* !ACE_HAS_VXTHREADS */   
[*]
[*]/// Collect pointers to thread descriptors of threads to be removed later.   
[*]ACE_Unbounded_Queue<ACE_Thread_Descriptor*> thr_to_be_removed_;
[*]
[*]/// Keeps track of the next group id to assign.   
[*]int grp_id_;
[*]
[*]/// Set if we want the Thread_Manager to wait on all threads before   
[*]/// being closed, reset otherwise.   
[*]int automatic_wait_;
[*]
[*]// = ACE_Thread_Mutex and condition variable for synchronizing termination.   
[*]#if defined (ACE_HAS_THREADS)   
[*]/// Serialize access to the <zero_cond_>.   
[*]ACE_Thread_Mutex lock_;
[*]
[*]/// Keep track of when there are no more threads.   
[*]ACE_Condition_Thread_Mutex zero_cond_;
[*]#endif /* ACE_HAS_THREADS */   
[*]
[*]ACE_Locked_Free_List<ACE_Thread_Descriptor, ACE_SYNCH_MUTEX> thread_desc_freelist_;
[*]
[*]private:
[*]#if ! defined (ACE_THREAD_MANAGER_LACKS_STATICS)   
[*]/// Pointer to a process-wide ACE_Thread_Manager.   
[*]static ACE_Thread_Manager *thr_mgr_;
[*]
[*]/// Must delete the thr_mgr_ if true.   
[*]static bool delete_thr_mgr_;
[*]
[*]/// Global ACE_TSS (ACE_Thread_Exit) object ptr.   
[*]static ACE_TSS_TYPE (ACE_Thread_Exit) *thr_exit_;
[*]#endif /* ! defined (ACE_THREAD_MANAGER_LACKS_STATICS) */   
[*]};
[*]
[*]#if defined (ACE_THREAD_MANAGER_LACKS_STATICS)   
[*]#define ACE_THREAD_MANAGER_SINGLETON_DEFINE \   
[*]      ACE_Singleton<ACE_Thread_Manager, ACE_SYNCH_MUTEX>;
[*]typedef ACE_Singleton<ACE_Thread_Manager, ACE_SYNCH_MUTEX> ACE_THREAD_MANAGER_SINGLETON;
[*]#endif /* defined (ACE_THREAD_MANAGER_LACKS_STATICS) */   
[*]
[*]ACE_END_VERSIONED_NAMESPACE_DECL
[*]
[*]#if defined (__ACE_INLINE__)   
[*]#include "ace/Thread_Manager.inl"   
[*]#endif /* __ACE_INLINE__ */   
[*]
[*]#include /**/ "ace/post.h"   
[*]#endif /* ACE_THREAD_MANAGER_H */




注意:必须在退出functor所属的线程的上下文中,向线程管理器登记这个退出functor.使用ACE_Thread_Manager::at_exit()方法登记退出functor;
    ACE_Thread_Manager::wait()会等待所有的子线程退出,而不管与那些线程相关联的是哪个任务,当你有不止一个任务正在执行的时候,使用这个特性将会很方便;
    注意:我们要把ACE_Thread_Manager类的实例当作一个单体对象使用;其原因是:在默认情况下,ACE会通过这个单体对象来管理所有的线程;尽管在大多数情况下,你会发现默认行为已经足够,你可以创建并使用多个线程管理器对象;
线程的取消:
    取消是一种你可以用以消灭(zap)正在运行线程的途径.任何线程退出处理器都不会被调用,线程专有存储空间也不会被释放.你的线程将消失.在某些情况下,取消也是一种"必要的邪恶":为了退出一个长时间运行的、只进行计算的线程,或是终止一个阻塞在阻塞式调用上的线程.在大多数情况下,应用终止时取消线程是有意义的;
    取消有以下几种模式:
    A、延迟取消:
       这种模式下,所有的取消操作都会被延迟到该线程的下一个取消点.取消点是代码中明确定义的点,在这个点上,线程或是已经阻塞,或是用ACE_Thread_Manager::testcancal()方法编写了显式的取消点.这种模式是用ACE构建的应用的默认模式;
    B、协作式取消:
       这种模式下,线程并没有被真正的取消,而是会在派生它们的ACE_Thread_Manager实例中被标记已取消.你可以调用ACE_Thread_Manager::testcalcel()方法来确定线程是否处在已取消状态.如果这样,你可以选择退出线程.这种模式避免了常规取消所带来的大多数讨厌的副作用.如果你想构建可移植的应用,就最好坚持使用这种取消模式;   
    C、异步取消:
       这种模式下,取消操作可以在任意时刻被处理;运行在这种模式下的线程可能会难以管理.你可以把任何线程的取消状态从启用改为禁用,以确保线程不会在执行关键代码时被取消.你还可以使用线程清理处理器,它们将在线程取消时被调用,以确保线程的各不变项在取消过程中得以维持.
    D、禁用取消:
       调用ACE_Thread::disablecancel(),可以完全禁止取消某个线程;   
    ACE_Thread_Manager::cancel_task()方法可以用来取消一个线程;
    下面的方法可以把线程的取消模式设置为异步取消模式:
    cancel_state new_state;
    new_state.cancelstate = PTHREAD_CANCEL_ENABLE;
    new_state.canceltype= PTHREAD_CANCEL_ASYNCHRONOUS;
    ACE_Thread::setcancelstate(new_state, 0);
更多文章,欢迎访问:http://blog.csdn.net/wallwind
页: [1]
查看完整版本: ACE_Thread_Manager-------ACE线程管理