【C++11】thread和this_thread
前言
本章节主要介绍C++11的并发库中的 thread 线程这个类。但是目的并不是将这个类讲解清楚,而是主要是介绍一些常用的点。我们没有必要为了记忆而记忆,遗忘是很正常的事情,我们不知道接口的时候,就可以查阅文档:
- 官方文档。可读性有点不高,但是新!
- 小编常用文档。这个文档的可读性较高,小编比较喜欢在这上面查阅一些C++的遗忘的语法知识。但是这个文档局限性较高,只有C++11及以下的语法,并没有C++14/C++17的语法。
同时,如果觉得文档查阅低效,现在有很多的AI可以辅助学习:豆包、deepseek、kimi、……配合这些资源都能快速对这些接口上手!
1. thread
学习 Linux 系统的时候大家肯定对 thread 已经不陌生了。在使用原生线程库的时候,很重的一个硬伤就是:参数的传递。幸好:C++11退出了线程库,采用了面向对象的编程思想,包装了线程库,极大的便利了开发者。
如下是一些C++11线程库的一些简介:
-
thread 库底层是对各个系统的线程库进行封装(简单来说就是采用条件编译),如 Linux 下的 pthread 库和 Windows 下 Thread 库等,所以 C++11 thread 库的第⼀个特点是可以跨平台,第⼆个特点是 Linux 和 Windows 下提供的线程库都是面向过程的,C++11 thread是库面向对象的,并且融合了⼀些C++11语言特点,如右值引用的移动语义,可变模板参数等,用起来会更好用⼀些。
-
来看 thread 的几个构造函数:

注意:-
空的构造:这是为了使用容器的时候,可以之间空构造一个节点。(例如:
vector) -
传入一个可执行对象:常用的就是 lambda。这个是常用的方式
-
不支持拷贝构造。
-
支持移动构造,这也是为了配合一些容器的使用!
-
案例一:
int main()
{
std::thread t1([]() {
for (int i = 0; i < 10; ++i)
{
std::cout << i << std::endl;
}
});
std::thread t2([]() {
for (int i = 10; i < 20; ++i)
{
std::cout << i << std::endl;
}
});
t1.join();
t2.join();
return 0;
}
显示器文件也是共享资源,存在临界资源的竞争问题。
案例二:
int main()
{
std::vector<std::thread> v(5); //开5个线程的空间。这里就注定了要使用空的构造
v.push_back(std::thread([]() {
for (int i = 0; i < 10; ++i)
{
std::cout << i << std::endl;
}
}));
for (auto& e : v)
{
if(e.joinable())
e.join();
}
return 0;
}
使用 vector 来管理线程。配合容器的使用,我们更好地实现一个简易的线程池。
下面还有这些方法,小编也不再做介绍了!

2. this_thread
在我们刚刚的案例中,有一个问题:我们想在我们线程内部获取我们的线程id怎么办呢?好像没有办法?这个时候 C++11 包装了一个命名空间:this_thread。提供了很多的关于当前线程的方法:


-
yield:这个接口的使用还是挺有场景的。
-
自旋锁的实现。在等待某个资源时,避免线程进入阻塞状态(可能导致上下文切换开销),而是通过循环 +
yield ()的方式短暂等待。 -
降低忙等待的 CPU 占用。当线程需要等待某个条件满足但又不适合使用条件变量时(如等待时间极短的情况),使用
yield ()可以减少 CPU 资源浪费。 -
优先级调整。在某些情况下,当前线程执行的任务优先级较低,希望优先让其他重要线程执行时。
但是也有注意:
-
yield()只是一个提示,操作系统不一定会立即切换到其他线程 -
过度使用 yield() 可能导致性能下降,因为频繁的线程切换会带来开销
-
对于长时间等待的场景,应优先使用条件变量(std::condition_variable)而非 yield() + 循环的方式
-
-
sleep_for和sleep_until
这两个函数的作用都是休眠当前线程。在一些场景下,我们不希望一个线程一直执行,但是没有成效。(死循环检测一些条件就绪)我们就可以给这样的线程设置一个休眠时间,从而把 CPU 资源交给其它线程避免进程切换的开销。
同时,想要使用这两个类,不得不学会使用的一个库就是:
chrono。
2.1 chrono库

这个库支持了关于时间的很多操作:
-
测量代码执行时间。
-
时长转换与运算。
-
获取系统当前时间。
3demo:
#include <iostream>
#include <chrono>
#include <ctime>
int main()
{
// 获取当前系统时间点
auto now = std::chrono::system_clock::now();
// 转换为time_t类型(传统C时间类型)
std::time_t now_c = std::chrono::system_clock::to_time_t(now);
// 格式化输出
std::cout << "当前时间: " << std::ctime(&now_c); // 例如: Wed Sep 26 10:00:00 2025
return 0;
}
关键特性与优势:
- 类型安全:不同时间单位的时长是不同类型,避免隐式转换错误。
- 高精度:支持纳秒级计时(取决于系统硬件)
- 灵活性:可自定义时间单位和存储类型。
- 可移植性:统一接口屏蔽了不同系统的时间实现差异。
std::chrono 特别适合需要精确计时、时间间隔计算或跨平台时间处理的场景,如性能测试、定时器实现、事件调度等。
配合 this_thread 使用,伪代码demo:
int main()
{
std::thread t1([]() {
std::this_thread::sleep_for(std::chrono::seconds(30));
//休眠三十秒
while (true)
{
//做一些检测……
//条件满足了
// if(/*xxx*/) break;
}
});
t1.join();
return 0;
}
完。
更多推荐


所有评论(0)