C++ 11后引入的新 thread库

使用

引入:

1
2
3
#include <thread>
using namespace std; //或者直接使用std::thread
//...

具体用法:

1
2
3
std::thread thread_object(_Fn &&_Fx, _Args**..._Ax);
//第一个参数是函数指针或函数对象也可以是lambda表达式
//第二个参数的函数的参数,若没有可以不填

示例

普通函数示例

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
#include <iostream>
#include <thread>
using namespace std;
//...
void func1(int a){
for(int i = 0; i < a ; i++){
cout<< a << endl;
}
}
void func2(int b){
for(int i = 0; i < b ; i++){
cout<< b << endl;
}
}
//...
int main(){
//填入参数int a = 50 即函数执行for循环50次
thread thd1(func1, 50);
thread thd2(func2, 50);
//等待线程
thd1.join();
thd2.join();

return 0;
}

函数对象示例

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
#include <iostream>
#include <thread>
using namespace std;
//...
class thread_obj1{
public:
void operator()(int a){
for(int i = 0 ; i < a ; i++){
cout << a << endl;
}
}
}

class thread_obj2{
public:
void operator()(int b){
for(int i = 0 ; i < b ; i++){
cout << b << endl;
}
}
}
//...
int main(){
//填入参数int a和b = 50 即函数执行for循环50次
thread thd1(thread_obj1, 50);
thread thd2(thread_obj1, 50);

thd1.join();
thd2.join();

return 0;
}

lambda表达式示例

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
#include <iostream>
#include <thread>
using namespace std;
//...
int main(){

auto func1 = [](int a){
for(int i = 0 ; i < a ; i++){
cout << a << endl;
}
}
auto func2 = [](int b){
for(int i = 0 ; i < b ; i++){
cout << b << endl;
}
}

thread thd1(func1, 50);
thread thd2(func2, 50);
//等待线程退出
thd1.join();
thd2.join();

return 0;
}

示例运行结果

1
2
3
4
5
6
7
8
1
2
1
2
2
1
2
...

可以看到执行是交叉执行,则说明方法正确。

join();函数

用于等待线程退出,当调用到该函数时,主线程将被阻滞,直到子线程运行完毕退出。如果不使用join(),而只是创建并运行线程,可能会导致main主线程退出后子线程仍然在运行,主线程退出后,所有在主线程中创建的变量以及开辟的内存空间都会销毁释放,若子线程在主线程销毁后仍然在访问主线程的变量或是内存地址,就会导致报错。

detach();函数

用于将主线程与子线程分离运行,相互独立,与join()不同的是,它会独立于主线程运行,相当于linux守护进程,主线程退出后,子线程随之退出,但是在实际使用中最好使用原子变量控制子线程的状态,当主线程即将退出时,将子线程的状态设置为false,退出子线程,然后主线程再结束,这是安全的做法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <thread>
#include <chrono>
#include <iostream>
std::atomic_bool isExit = false;
void ThreadFunc(){
while(!isExit){
std::cout << "sub thread!" << std::endl;
}
}
int main(){
thread th(ThreadFunc);
th.detach();
for(int i = 0; i < 1000; i++){
std::cout << "main thread!" << std::endl;
}
isExit = true; //循环完毕,将子线程状态设置为退出状态,子线程就会退出while循环
return 0; //主线程返回,并退出主线程
}

编译运行结果:

1
2
3
4
5
6
7
8
sub thread!
sub thread!
main thread!
main thread!
sub thread!
main thread!
sub thread!
...

this_thread::sleep_for();函数

函数原型:

std::this_thread::sleep_for(const chrono::duration<_Rep, _Period>& _Rel_time);

用于释放一段时间CPU资源,说人话就是让当前线程停止一段时间

参数const chrono::duration<_Rep, _Period>& _Rel_time有简化写法,以下是两种写法:

第一种:std::this_thread::sleep_for(20s);

第二种:std::this_thread::sleep_for(std::chrono::seconds(20));

joinable();函数

原型: bool joinable(); 返回值为布尔值

该函数用于检测线程是否可以被join()detach()相同线程不能多次join()也不得join()detach()