ace_thread 参数如何正确配置使用?

99ANYc3cd6
预计阅读时长 29 分钟
位置: 首页 参数 正文

ace_thread 并不是一个像 C++11 std::thread 那样直接创建线程的类,在 ACE (Adaptive Communication Environment) 框架中,创建和管理线程主要通过以下几个类来完成:

ace_thread 参数
(图片来源网络,侵删)
  1. ACE_Thread: 一个底层的、C风格的线程管理类,提供创建、挂起、恢复、退出等基本功能。
  2. ACE_Task_Base: 更高级的抽象,通常用于管理一个或多个线程,一个 Task 可以有自己的消息队列,线程执行的是 Task 中定义的 svc() (service) 方法。
  3. ACE_Thread_Manager: 线程管理器,用于集中创建、管理、同步和销毁一组线程,是 ACE 中最常用和推荐的线程管理方式。

讨论 "ace_thread 参数" 实际上是讨论这些类创建线程时需要的参数,下面我将分别对这几个核心类进行详细说明。


ACE_Thread 类 (底层 C 风格)

ACE_Thread 的核心方法是 spawn(),用于创建一个新的线程,它的参数最复杂,因为它提供了对线程属性的细粒度控制。

核心方法: spawn()

spawn() 有多个重载版本,最常用和功能最全的是以下这个:

// 注意:这是一个简化的签名,实际参数更多,但核心是这些
ACE_THR_FUNC_RETURN ACE_Thread::spawn (
  ACE_THR_FUNC func, // 线程要执行的函数指针
  void *arg,         // 传递给线程函数的参数
  long flags,        // 线程创建标志 (是否分离、是否挂起等)
  ACE_Thread_ID &thr_id, // 用于接收新创建线程的ID
  long priority,     // 线程优先级
  int grp_id,        // 线程组ID (通常用0)
  ACE_thread_t *thread_handle // 用于接收线程句柄 (可选)
);

参数详解

参数 类型 描述
func ACE_THR_FUNC 线程函数指针,这是一个函数指针类型,定义如下:
typedef ACE_THR_RETURN (*ACE_THR_FUNC)(void *);
它指向一个无参数、返回 ACE_THR_RETURN (通常是 intvoid*) 的函数,并且接受一个 void* 类型的参数,这是线程的入口点。
arg void * 线程函数参数,你可以将任何数据结构的指针转换为 void* 传递给线程函数,在线程函数内部,需要将其强制转换回原来的类型。注意:如果参数是局部变量的地址,要确保在线程开始执行前该变量生命周期不会结束。
flags long 线程创建标志,这是最复杂的参数,通过位或 () 组合多个标志,常用标志包括:
- THR_NEW_LWP: 创建一个新的轻量级进程(内核线程)。
- THR_DETACHED: 创建一个分离线程(detached thread),这种线程结束后,其资源会被自动回收,不能被 join,这是最常用的模式之一。
- THR_JOINABLE: 创建一个可汇合线程(joinable thread),默认值,主线程可以调用 join() 来等待它结束并回收资源。
- THR_SUSPENDED: 创建一个挂起线程,线程创建后会立即暂停,直到其他线程调用 resume() 唤醒它。
- THR_INHERIT_SCHED: 继承创建者线程的调度策略。
- THR_BOUND: 创建一个绑定到特定处理器的线程(平台相关)。
thr_id ACE_Thread_ID & 输出参数,一个引用,用于接收新创建线程的唯一标识符。
priority long 线程优先级,指定新线程的优先级,数值越高,优先级越高。注意:修改线程优先级是平台相关的操作,且需要特定权限。
grp_id int 线程组ID,将新线程加入一个现有的线程组,对于简单应用,通常设为 0。
thread_handle ACE_thread_t * 可选输出参数,一个指针,用于接收操作系统原生的线程句柄(在 Windows 上是 HANDLE,在 POSIX 系统上是 pthread_t)。

示例

#include "ace/Thread.h"
#include <iostream>
// 线程函数
int worker_thread(void *arg) {
    int *value = static_cast<int*>(arg);
    std::cout << "Worker thread started. Received value: " << *value << std::endl;
    // 模拟工作
    ACE_OS::sleep(2);
    std::cout << "Worker thread finished." << std::endl;
    return 0;
}
int main() {
    ACE_Thread_ID thr_id;
    int my_data = 123;
    // 创建一个分离的、可汇合的线程
    long flags = THR_DETACHED | THR_JOINABLE; // 这里THR_DETACHED会覆盖THR_JOINABLE,通常只用一个
    // 更常见的用法是只选一个,THR_DETACHED
    flags = THR_DETACHED;
    if (ACE_Thread::spawn(worker_thread, &my_data, flags, thr_id) == -1) {
        std::cerr << "Failed to spawn thread." << std::endl;
        return 1;
    }
    std::cout << "Main thread: Worker thread spawned with ID: " << thr_id << std::endl;
    // 如果是THR_DETACHED,不能join,如果是THR_JOINABLE,可以在这里join。
    // ACE_Thread::join(thr_id); 
    ACE_OS::sleep(3); // 让主线程等一下,以便观察子线程输出
    return 0;
}

ACE_Task_Base 类 (高级抽象)

使用 ACE_Task 是更 ACE-thonic 的方式,你创建一个 Task 类,重写其 svc() 方法,然后调用 activate() 来激活(即创建线程)。

ace_thread 参数
(图片来源网络,侵删)

核心方法: activate()

// 简化签名
virtual int activate (long flags = THR_NEW_LWP | THR_JOINABLE,
                      int n_threads = 1,
                      int force_active = 0,
                      long priority = ACE_DEFAULT_PRIORITY,
                      int grp_id = -1,
                        ACE_Task_Base *task = 0,
                        ACE_hthread_t *thread_handles = 0,
                        void *stack = 0,
                        size_t stack_size = 0);

参数详解

参数 类型 描述
flags long 线程创建标志,与 ACE_Thread::spawn 中的 flags 含义完全相同,THR_DETACHED, THR_JOINABLE 等。
n_threads int 要创建的线程数量,默认为 1,你可以指定一个大于 1 的数,ACE_Task 会为你创建一个线程池,所有线程都执行同一个 svc() 方法。
priority long 线程优先级,与 ACE_Thread::spawn 中的 priority 含义相同。
grp_id int 线程组ID,含义同上。
task ACE_Task_Base * 用于激活的Task对象,通常为 this
thread_handles ACE_hthread_t * 可选输出参数,一个数组,用于接收所有创建的线程的句柄。
stack void * 线程栈地址,可选,用于指定线程栈的起始地址。
stack_size size_t 线程栈大小,可选,用于指定线程栈的大小。

示例

#include "ace/Task.h"
#include <iostream>
class MyTask : public ACE_Task_Base
{
public:
    // svc() 方法是线程执行的入口点
    virtual int svc() override
    {
        // ACE_Thread::self() 获取当前线程ID
        std::cout << "Thread in svc() started. Thread ID: " << ACE_Thread::self() << std::endl;
        // 模拟工作
        ACE_OS::sleep(2);
        std::cout << "Thread in svc() finished." << std::endl;
        return 0; // 返回0表示成功
    }
};
int main()
{
    MyTask task;
    // 激活Task,创建1个分离线程
    // 注意:THR_DETACHED 是最常用的标志
    if (task.activate(THR_DETACHED) == -1)
    {
        std::cerr << "Failed to activate task." << std::endl;
        return 1;
    }
    std::cout << "Main thread: Task activated." << std::endl;
    ACE_OS::sleep(3); // 等待线程完成
    return 0;
}

ACE_Thread_Manager 类 (推荐方式)

ACE_Thread_Manager (简称 TM) 是 ACE 中管理线程的“瑞士军刀”,它通过 spawn_n() 方法来创建和管理一组线程。

核心方法: spawn_n()

// 简化签名
virtual int spawn_n (ACE_THR_FUNC func,
                     void *args = 0,
                     long flags = THR_NEW_LWP | THR_JOINABLE,
                     int n_threads = 1,
                     long priority = ACE_DEFAULT_PRIORITY,
                     int grp_id = -1,
                     void *stack = 0,
                     size_t stack_size = 0,
                     ACE_Task_Base *task = 0);

参数详解

spawn_n() 的参数几乎与 ACE_Task::activate() 完全相同,因为它在内部也是调用 ACE_Thread::spawn 来创建线程的。

参数 类型 描述
func ACE_THR_FUNC 线程函数指针,与 ACE_Thread::spawn 中的 func 相同。
args void * 线程函数参数,所有新创建的线程将收到同一个 args 指针。
flags long 线程创建标志,同上。
n_threads int 要创建的线程数量
priority long 线程优先级
grp_id int 线程组ID
task ACE_Task_Base * 可选Task对象,如果提供,线程将执行该Task的 svc() 方法。

ACE_Thread_Manager 的优势

  1. 集中管理:你可以一次性创建一组线程,然后通过 TM 对象统一管理它们。
  2. 便捷的等待wait() 方法会等待所有由该 TM 创建的线程结束。
  3. 便捷的终止wait() 方法可以带一个超时参数,也可以调用 cancel() 来强制终止所有线程。
  4. 获取结果:可以获取线程的退出状态。

示例

#include "ace/Thread_Manager.h"
#include "ace/OS.h"
#include <iostream>
int worker_thread(void *arg)
{
    std::cout << "Worker thread running. Arg: " << *static_cast<int*>(arg) << std::endl;
    ACE_OS::sleep(2);
    return 0; // 返回码
}
int main()
{
    ACE_Thread_Manager tm;
    int shared_arg = 456;
    // 使用Thread Manager创建2个分离线程
    long flags = THR_DETACHED;
    if (tm.spawn_n(worker_thread, &shared_arg, flags, 2) == -1)
    {
        std::cerr << "Error spawning threads with Thread Manager." << std::endl;
        return 1;
    }
    std::cout << "Main thread: Spawned 2 threads via Thread Manager." << std::endl;
    // wait() 会阻塞,直到所有由tm管理的线程都结束
    // 因为是THR_DETACHED,它们执行完就自动结束了
    tm.wait();
    std::cout << "Main thread: All managed threads have finished." << std::endl;
    return 0;
}

总结与最佳实践

类/方法 风格 核心参数 适用场景
ACE_Thread::spawn() 底层 C 风格 func, arg, flags, priority 需要对线程进行最底层、最精细控制的场景,不常用,除非有特殊需求。
ACE_Task::activate() 高级 C++ 风格 flags, n_threads, priority 当你的线程逻辑封装在一个类中,且可能需要处理消息队列时,是创建单个或多个同类线程的好方法。
ACE_Thread_Manager::spawn_n() 推荐的管理方式 func, args, flags, n_threads, priority 最常用,当你需要创建、管理和等待一组线程时,这是最简单、最强大的方式。

最佳实践建议:

  1. 首选 ACE_Thread_Manager:对于绝大多数多线程应用,使用 ACE_Thread_Manager 是最简单、最不容易出错的方式,它提供了完整的生命周期管理。
  2. 次选 ACE_Task:如果你的线程逻辑比较复杂,或者你希望利用 ACE 的消息队列机制(ACE_Message_Queue),那么将线程逻辑封装在 ACE_Task 中是一个非常好的设计。
  3. 谨慎使用 ACE_Thread:除非你确实需要 ACE_Thread 提供的那些底层控制能力(如 THR_BOUNDTHR_SUSPENDED),否则尽量避免直接使用它,因为它更容易出错(例如忘记管理线程资源)。
ace_thread 参数
(图片来源网络,侵删)
-- 展开阅读全文 --
头像
Aliware17 R3拆机步骤是怎样的?
« 上一篇 今天
惠普pavilion g4拆机步骤详解?
下一篇 » 今天

相关文章

取消
微信二维码
支付宝二维码

最近发表

标签列表

目录[+]