【C++】C++11 Thread线程库的基本使用
创建线程
C++11中,我们可以使用函数指针、函数对象或lambda表达式来实现。创建线程的基本语法如下:
1 |
|
function_name
是线程入口点的函数或可调用对象args...
是传递给函数的参数
创建线程后,我们可以使用t.join()
等待线程完成,或者使用t.detach()
分离线程,让它在后台运行。
Example: 1
2
3
4
5
6
7
8
9
10
11
void print_message() {
std::cout << "Hello, world!" << std::endl;
}
int main() {
std::thread t(print_message);
t.join();
return 0;
}
传递参数
使用函数参数、全局变量、引用都可以向线程传递参数 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
void print_message(const std::string& message) {
std::cout << message << std::endl;
}
void increment(int& x) {
++x;
}
int main() {
std::string message = "Hello, world!";
std::thread t(print_message, message);
t.join();
int x = 0;
std::thread t2(increment, std::ref(x));
t2.join();
std::cout << x << std::endl;
return 0;
}
需要注意的是,当我们使用引用传递参数时,我们需要使用
std::ref
来包装引用,否则编译器会报错。
在 C++ 中,std::thread
构造函数模板接受可调用对象和参数时,会复制传递给它们的参数,防止因多个线程同时修改同一数据而可能引起的访问冲突或数据竞争。然而,在某些情况下,你实际上希望线程直接作用于原始变量或对象,而不是副本,这里的
increment
函数设计为修改传递给它的原始整数
等待线程完成
使用t.join()
方法来等待线程完成
1 |
|
分离线程
与 join
不同,我们可能不需要等待线程完成,而是希望它在后台运行
1 |
|
joinable()
joinable()方法返回一个布尔值,如果线程可以被join()或detach(),则返回true,否则返回false。如果我们试图对一个不可加入的线程调用join()或detach(),则会抛出一个std::system_error异常。
1 |
|
线程函数中的数据未定义错误
传递临时变量
1 |
|
我们创建了一个名为t
的线程,将foo
函数以及一个临时变量1
作为参数传递给(int引用)。这样会导致在线程函数执行时,临时变量1
被销毁,从而导致未定义行为。
传递指向局部变量的指针或引用:
1 |
|
Reference
【C++】C++11 Thread线程库的基本使用
https://jerry20000730.github.io/wiki/程序语言/C++/multi-threading1/