当前位置: 首页 > news >正文

C++ 时间库和线程库学习笔记(Chrono 与 Thread)

💡 C++ 标准库笔记(时间库 & 线程库)

📅 Part 1:时间库 <chrono>

🧩 基本概念

C++ 的 <chrono> 库提供了用于处理时间点(time_point)时间段(duration)时钟(clock) 的类模板,是处理时间相关操作的标准方式。

概念简介
clock时钟,用于获取当前时间
time_point一个具体的时间点
duration表示两个时间点之间的时间段

⏰ 常用时钟类型

时钟类型说明
std::chrono::system_clock系统当前时间,可以转换为 time_t(适合日志)
std::chrono::steady_clock单调时钟,适合计时,不受系统时间影响
std::chrono::high_resolution_clock高精度计时器,通常是 steady_clock 的别名
auto now = std::chrono::system_clock::now(); // 当前系统时间
std::time_t now_c = std::chrono::system_clock::to_time_t(now);
std::cout << std::ctime(&now_c); // 格式化打印当前时间

🧮 计时器使用示例

auto start = std::chrono::high_resolution_clock::now();

// 要计时的操作

auto end = std::chrono::high_resolution_clock::now();
auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
std::cout << "耗时:" << duration.count() << " 毫秒\n";

🕒 线程延时操作

引入字面量单位
using namespace std::chrono_literals;

std::this_thread::sleep_for(1s); // 延时1秒
std::this_thread::sleep_until(std::chrono::high_resolution_clock::now() + 2s); // 等到2秒后

🧵 Part 2:线程库 <thread> 和同步工具 <mutex>

🚀 基础用法:std::thread

  • 创建线程时需要提供一个可调用对象(函数、lambda、函数对象等)。
  • 线程启动后立即运行,直到结束或主线程 join()detach()
std::thread t([] {
    std::cout << "Thread is running\n";
});
t.join(); // 等待线程执行完毕

👬 join 与 detach 区别

方法含义
join()主线程等待子线程执行完
detach()子线程脱离主线程独立运行,不能再 join,生命周期由系统控制
❗注意若线程在析构前未 joindetach,程序将 terminate()

🔒 线程安全与同步:std::mutex

🚧 为什么需要锁

多个线程读写共享变量(如 sum)会导致数据竞争(race condition),造成不可预知的错误结果或崩溃。

unsigned long long sum = 0;
std::mutex mtx;

auto thread_func = [&]() {
    std::lock_guard<std::mutex> lock(mtx); // 自动加锁解锁
    sum += 1;
};

✅ 推荐使用 std::lock_guard

RAII 风格自动管理锁,异常安全,推荐使用。

std::lock_guard<std::mutex> lock(mtx);

🧠 多线程案例分析

✅ 单线程执行(对照组)

for (const auto& array : vector) {
    for (int i : array) {
        sum += i; // 单线程无竞争
    }
}

❌ 多线程 + 共享变量(无锁)→ 错误结果

// 多线程对 sum 写入,未加锁,会造成数据竞争
threads.push_back(std::thread([&sum, &array] {
    for (int i : array) {
        sum += i; // ❌ 竞态条件
    }
}));

✅ 使用 mutex 保护(但效率低)

std::mutex mtx;
threads.push_back(std::thread([&sum, &array, &mtx] {
    for (int i : array) {
        std::lock_guard<std::mutex> lock(mtx); // 🔒 每次加锁,效率差
        sum += i;
    }
}));

✅ 优化:局部变量累加后再锁一次

std::mutex mtx;
threads.push_back(std::thread([&sum, &array, &mtx] {
    unsigned long long local_sum = 0;
    for (int i : array) {
        local_sum += i; // 局部变量无锁
    }
    std::lock_guard<std::mutex> lock(mtx); // 🔒 只锁一次
    sum += local_sum;
}));

🧠 补充知识点

🧮 栈溢出风险

  • 栈是线程的私有资源,大小有限。
  • std::array<int, 5000000> 太大会导致栈溢出,应放入堆中(如 std::vector<std::array<...>>)。

🧪 std::asin, std::acos, std::atan, std::sqrt

  • 为了制造“有用但无意义”的运算负载。
  • 用于模拟真实计算,提高 benchmark 的可信度。

✨ 编码建议 & 小技巧

  • __FUNCTION__ 宏:打印当前函数名(含命名空间)。
  • 使用 constexpr 设定常量,提升可读性和效率。
  • 尽量避免在循环中频繁加锁,可采用局部变量聚合后统一加锁。

🔚 总结:学习路线建议

学习阶段建议内容
初学者掌握 std::thread, std::mutex, std::lock_guard 基础使用方法
进阶者熟悉竞态条件调试、优化加锁策略、合理使用 sleep_for, sleep_until
拓展学习学习 std::future, std::promise, std::condition_variable 等更复杂的同步机制

相关文章:

  • C++ 中的双指针技巧:高效解决数组和链表问题
  • 华为openEuler欧拉系统
  • unity运行时进行录制并保存(可进行二次加载包含场景中生成动态物体)
  • AMS 启动流程管理进程与Binder的关联
  • LeetCode.234. 回文链表
  • 峰飞航空与合肥开启全面合作,打造先进空中立体多维交通运输生态
  • 国家出手肥胖问题,AI减肥起风了
  • Element Plus 图标使用方式整理
  • 【力扣hot100题】(076)买卖股票的最佳时机
  • 基于华为云kubernetes的应用多活的示例
  • 基于PyQt5的企业级生日提醒系统设计与实现
  • AI智能体需求研究报告:小红书、知乎、抖音等平台用户需求深度分析
  • 【QT】QT中的文件IO
  • 【SpringBoot】98、SpringBoot中整合springdoc-openapi-ui接口文档
  • 网络出故障时,四大表(MAC表、ARP表、路由表、转发表)怎么查?看看这套排查顺序
  • 操作系统常用命令
  • 点击抽奖功能总结
  • 更改CMD背景图片
  • [特殊字符] 手机连接车机热点并使用 `iperf3` 测试网络性能
  • 让你的MCP符合openai协议
  • 网站建设-部署与发布/百度账号申诉
  • 网站设计公司 广州/seo优化点击软件
  • 营销型网站建设明细报/搜索引擎优化举例说明
  • 海外网站推广/网络营销课程个人总结3000字
  • 网站建设教学视频百度云盘/优化师助理
  • 公司做年审在哪个网站/简述网络营销与传统营销的整合