std::thread 是 C++11 标准库中的一个类,用于创建和管理线程。它提供了一种并发编程的机制,使得一个程序可以同时执行多个任务,提高程序的执行效率和响应能力。

# 1、构造函数及其参数

std::thread 的构造函数有多种形式,常见的使用方法如下:

  1. 普通函数:

    1
    2
    void function_name(int arg1, double arg2);
    std::thread t1(function_name, 10, 3.14);

    这里 function_name 是要在线程中执行的函数名,后面的参数是传递给函数的参数。

  2. 成员函数:
    这里需要注意,传递成员函数时需要同时传递对象实例进行绑定:

    1
    2
    3
    4
    5
    6
    class MyClass {
    public:
    void member_function(int arg1);
    };
    MyClass obj;
    std::thread t2(&MyClass::member_function, &obj, 20);

    这里 &MyClass::member_function 是要执行的成员函数指针, &obj 是类实例的指针, 20 是传递给成员函数的参数。

经实测,如果我们要传递的成员函数是重载的函数调用运算符 operator() ,则可以省略对成员函数的显式声明。(具体见下文示例代码)

  1. Lambda 表达式:
    1
    2
    3
    4
    5
    std::thread t3(
    [](int arg) {
    std::cout << "Lambda: " << arg << std::endl;
    },
    30);

    这里使用 Lambda 表达式直接定义了一个匿名函数,并将参数 30 传递给它。

此外,如果实际场景中需要向线程传递引用时,需要用到 std::ref

# 2、线程管理方法

  1. join:

    1
    t1.join();

    等待线程 t1 完成。主线程会阻塞直到 t1 执行完毕。

  2. detach:

    1
    t2.detach();

    将线程 t2 分离,使其在后台运行,主线程不再等待它。分离后的线程无法再与主线程交互。

  3. joinable:

    1
    2
    3
    if(t3.joinable()) {
    t3.join();
    }

    检查线程是否可以被 join ,避免重复 joindetach 导致错误。

# 3、其他方法

  • get_id: 获取线程 ID。

    1
    2
    std::thread::id id = t1.get_id();
    std::cout << "Thread ID: " << id << std::endl;

  • hardware_concurrency: 获取系统支持的并发线程数。

    1
    2
    unsigned int num_threads = std::thread::hardware_concurrency();
    std::cout << "Number of concurrent threads supported: " << num_threads << std::endl;

# 4、示例代码

以下是一个使用 std::thread 的完整示例,展示了如何创建和管理线程:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#include <iostream>
#include <thread>
#include <vector>

// 普通函数
void print_numbers(int start, int end) {
for(int i = start; i <= end; ++i) {
std::cout << i << " ";
} std::cout << std::endl;
}

// 成员函数
class Printer {
public:
void operator()(const std::string& message, int count) {
for(int i = 0; i < count; ++i) {
std::cout << message << " ";
} std::cout << std::endl;
}
};

int main() {
// 创建线程执行普通函数
std::thread t1(print_numbers, 1, 10);

// 创建线程执行成员函数
Printer printer;
std::thread t2(printer, "Hello", 5);

// 使用 lambda 表达式创建线程
std::thread t3([]() {
std::cout << "Lambda thread" << std::endl;
});

// 等待线程完成
t1.join();
t2.join();
t3.join();

return 0;
}

# 5、注意事项

  1. 资源管理:确保线程执行完毕,避免资源泄漏。常用 joindetach
  2. 数据同步:多线程访问共享数据时,需使用同步机制(如 std::mutex )避免数据竞争。
  3. 异常处理:线程中抛出的异常不会被主线程捕获,需要在线程内部处理。

通过 std::thread ,可以方便地在 C++ 中实现多线程并发编程,提高程序的执行效率和响应速度。

更新于

请我喝杯咖啡吧~

Rick 微信支付

微信支付

Rick 支付宝

支付宝