[TOC]

概述

文章参考:https://blog.csdn.net/Trouble_provider/article/details/85268764

在c++ 中,程序默认是只有一个Main Thread运行的,其入口函数是主函数main(),其中若开辟了其他的新的子线程,对这些子线程的处理方式有两种,

一种是Join(),即main thread在被join的子线程没执行完的这段时间里,什么也不做,直到子线程执行完毕,才会继续向下执行
另一种是Detach(),如果没有其他一些同步措施的话,此时 子线程和main thread 完全分离,两个线程自顾自的运行,main thread可以不等子线程运行完,就提前结束。

(ps. 这里有个需要注意的地方,如果主线程 运行完毕了的话,那些被detach的线程也会随着主线程的销毁而被挂起,此时里面本应cout出来显示的内容也将不再显示!!)

所以,此时就有一个问题,如何让 主线程 在被开辟的子线程运行的时候,不只是干等着,也能做自己的事情,等到子线程运行完了,然后再结束主线程呢?

答案是: 利用detach() + 条件变量来进行线程同步

下面是代码:(代码中还有控制子线程运行频率的功能)

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
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
#include <iostream>       // std::cout
#include <thread> // std::thread, std::this_thread::sleep_for
#include <chrono> // std::chrono::seconds
#include <mutex>

using namespace std;
using namespace chrono; //chrono计时器 namespace

using milliseconds_duration = std::chrono::duration<double, std::milli>; //milli = ratio<1,1000>
using seconds_duration = std::chrono::duration<double,std::ratio<1,1>>;

#define SUB_THREAD_NUM 1

high_resolution_clock::time_point tps[SUB_THREAD_NUM][2]; //建立一个Time_point类型的数组,每个subThread都有一个start_tp、一个end_tp
milliseconds_duration t1;
int call_intervak_t1 = 5; //执行速度 5ms call 1次

bool thread1_ended = false; //使用detach时,需要独立地提供一种同步机制来等待线程完成


void pause_thread_second(int n)
{
std::this_thread::sleep_for(std::chrono::seconds(n));

}

void pause_thread_millisecond(int n)
{
std::this_thread::sleep_for(std::chrono::milliseconds(n));

}

//要以一定的频率调用该函数
void threadFunc1()
{
pause_thread_millisecond(1);
cout << "Thread :" << this_thread::get_id() << endl;
}

void Func1()
{
int i = 10;
double run_time = 0.0f;
while (i--)
{
tps[0][0] = high_resolution_clock::now(); //start_timepoint
threadFunc1();
tps[0][1] = high_resolution_clock::now(); //end_tp
t1 = duration_cast<milliseconds_duration>(tps[0][1] - tps[0][0]);
if (t1.count() < call_intervak_t1) pause_thread_millisecond(call_intervak_t1 - t1.count()); //若执行时间比规定的hz快,则sleep一段时间

//看是否达到了规定的频率
tps[0][1] = high_resolution_clock::now();
t1 = duration_cast<milliseconds_duration>(tps[0][1] - tps[0][0]);
run_time += t1.count();
cout << "Thread " << this_thread::get_id() << "has ran " << run_time << " ms" << endl;
}
cout << "Sub thread " << this_thread::get_id() << " ended." << endl;
thread1_ended = true; //同步标志,线程1已结束
}

int main()
{
auto n = thread::hardware_concurrency();
cout << "CPU核心数为:\t" << n << endl;
thread myThread(Func1);
myThread.detach();
while (!thread1_ended) //同步机制等待 thread1结束
{
//此处除了 pause之外, 主线程可以做其他一切自己想做的事情
pause_thread_second(1);
}
pause_thread_second(1);
cout << "Main thread " << this_thread::get_id() << " ended." << endl;
return 0;
}