C++ - 多线程之线程管理函数
1. 获取线程 id 函数 get_id()的使用
该函数在命名空间std::this_thread下。作用是获取当前线程的id。
#include <iostream>
#include <thread>
using namespace std;
//No.1 get_id() 获取线程id
void threadFunc() {
cout << "get_id() 子线程id: " << this_thread::get_id() << endl;
using namespace this_thread;
cout << "get_id() 子线程id: " << get_id() << endl;
}
void test01() {
cout << "主线程id: " << this_thread::get_id() << endl;
thread t1(threadFunc);
t1.join();
}
int main() {
test01();
return 0;
}
运行结果:
2. 延时函数sleep_for()的使用
该函数在命名空间std::this_thread下。作用是延时。
#include <iostream>
#include <thread>
#include <chrono>
using namespace std;
//No.2 sleep_for() 延时函数
void threadSleepFor() {
using namespace this_thread;
cout << "子线程id: " << get_id() << " 线程启动!" << endl;
this_thread::sleep_for(2s); //文本重载方式 延时两秒
sleep_for(chrono::seconds(2)); //延时两秒
using namespace chrono;
sleep_for(seconds(2));
cout << "子线程id: " << get_id() << " 线程结束!" << endl;
}
void test02() {
thread t2(threadSleepFor);
t2.join();
}
int main() {
test02();
return 0;
}
线程启动后, 在线程处理函数中,会延时一段时间。延时结束后,继续执行未执行完的线程处理函数。
运行结果:
3. 线程让步函数yield()的使用
该函数在命名空间std::this_thread下。作用是让当前线程让步,让操作系统执行另一个线程。
#include <iostream>
#include <thread>
#include <chrono>
#include <windows.h>
using namespace std;
//No.3 yield() 线程让步(让线程放弃执行, 让操作系统调用另一个线程执行)
void threadYield(chrono::milliseconds duration) { //间隔时间ms
using namespace this_thread;
cout << "yield: 子线程id: " << get_id() << " 线程开始!" << endl;
//使用高精度时钟获取当前时间
auto startTime = chrono::high_resolution_clock::now();
auto endTime = startTime + duration;
do {
//线程让步
yield();
} while (chrono::high_resolution_clock::now() < endTime);
cout << "yield: 子线程id: " << get_id() << " 线程结束!" << endl;
}
//chrono::microseconds 微秒
void test03() {
thread at[5];
//线程1让步 5 秒
at[0] = thread(threadYield, chrono::milliseconds(5000));
//其余四个线程让步 0 秒(每隔一秒创建一个线程)
for (int i = 1; i < 5; i++) {
this_thread::sleep_for(1s);
at[i] = thread(threadYield, chrono::milliseconds(0));
}
for (auto& th : at) {
th.join();
}
}
int main() {
test03();
return 0;
}
由下面的运行结果可知,第一个(线程id为12304)的 线程会等待5秒(线程让步5秒),
此时操作系统会执行下面的四个线程,待5秒之后,让步的线程(线程id为12304)的线程处理函数继续向下执行。
运行结果:
4. 阻塞线程函数sleep_until()的使用
该函数在命名空间std::this_thread下。作用是阻塞当前线程,直到sleep_time溢出。
#include <iostream>
#include <thread>
#include <chrono>
#include <iomanip>
#include <windows.h>
using namespace std;
void threadFunc() {
cout << "get_id() 子线程id: " << this_thread::get_id() << endl;
using namespace this_thread;
cout << "get_id() 子线程id: " << get_id() << endl;
}
//No.4 sleep_until() 阻塞当前执行线程 直到sleep_time溢出
void threadSleepUntil() {
cout << "sleep_until: 子线程id: " << this_thread::get_id() << " 线程开始!" << endl;
time_t tt = chrono::system_clock::to_time_t(chrono::system_clock::now());
tm* ptm = new tm;
localtime_s(ptm, &tt);
cout << put_time(ptm, "%X") << endl;
//设置sleep_time为5秒
for (int i = 0; i < 5; i++)
{
++ptm->tm_sec;
}
if (ptm != nullptr) {
this_thread::sleep_until(chrono::system_clock::from_time_t(mktime(ptm)));
}
cout << put_time(ptm, "%X") << endl;
cout << "sleep_until: 子线程id: " << this_thread::get_id() << " 线程结束!" << endl;
}
void test04() {
thread t1(threadSleepUntil);
this_thread::sleep_for(1s);
thread t2(threadFunc);
t1.join();
t2.join();
}
int main() {
test04();
return 0;
}
由下面的运行结果可知,线程t1会进入阻塞状态(sleep_time)阻塞5秒钟,然后t2线程会执行,5秒后t1线程退出阻塞状态,继续执行t1线程的线程处理函数。
运行结果: