乐途乐途
主页
  • 计算机基础

    • TCP/IP
    • Linux
    • HTTP
  • 数据库

    • SQL
    • MySQL 5.7
  • 编程语言

    • C
    • C++
    • Java SE
    • Python2
    • Python3
  • 数据格式

    • JSON
    • XML
  • 认证与安全

    • JWT
  • 工具

    • Markdown
  • Git

    • GitFlow
  • Quartz

    • Quartz
  • Java

    • Maven 入门
    • Maven 进阶
    • MyBatis
    • Spring
    • Spring MVC
  • Java

    • Spring Boot
    • Spring Cloud
    • Spring Cloud Alibaba
    • Spring Security
    • Spring AI
    • Spring Batch
    • Kafka
    • Java 设计模式
  • 缓存

    • Redis
  • 搜索引擎

    • Elasticsearch
  • 分布式协调

    • ZooKeeper
联系
阿里云
主页
  • 计算机基础

    • TCP/IP
    • Linux
    • HTTP
  • 数据库

    • SQL
    • MySQL 5.7
  • 编程语言

    • C
    • C++
    • Java SE
    • Python2
    • Python3
  • 数据格式

    • JSON
    • XML
  • 认证与安全

    • JWT
  • 工具

    • Markdown
  • Git

    • GitFlow
  • Quartz

    • Quartz
  • Java

    • Maven 入门
    • Maven 进阶
    • MyBatis
    • Spring
    • Spring MVC
  • Java

    • Spring Boot
    • Spring Cloud
    • Spring Cloud Alibaba
    • Spring Security
    • Spring AI
    • Spring Batch
    • Kafka
    • Java 设计模式
  • 缓存

    • Redis
  • 搜索引擎

    • Elasticsearch
  • 分布式协调

    • ZooKeeper
联系
阿里云
  • C++ 学习路径
  • 第1章 C++概述与开发环境

    • C++ 语言概述与编译模型
    • 第一个 C++ 程序与规范
    • 开发环境配置
    • 预处理指令详解
  • 第2章 基本语法与类型系统

    • 变量与基本类型
    • 类型转换
    • 枚举类型
    • 引用与指针
    • 数组与 stdarray
    • 字符串与原始字符串字面量
    • const 与 constexpr
    • nullptr 与空指针
    • 类型推导 auto 与 decltype
    • 基于范围的 for 循环
    • 值类别全面解析
    • char16_t 与 char32_t
    • static_assert 编译期断言
  • 第3章 函数与重载

    • 函数声明与定义
    • 函数重载
    • 默认参数与内联函数
    • Lambda 表达式
    • 函数对象与 stdfunction
    • 后置返回类型与 noexcept
  • 第4章 类与对象

    • 类的基本定义
    • 构造函数与析构函数
    • 拷贝控制
    • 移动构造函数与移动赋值
    • 列表初始化与类内初始化器
    • 静态成员与嵌套类
    • 友元
    • =default 与 =delete
  • 第5章 继承与多态

    • 继承基础
    • 虚函数与多态
    • 虚函数表与动态绑定原理
    • 虚析构函数
    • 抽象类与纯虚函数
    • 多重继承与虚继承
    • 继承构造函数
  • 第6章 运算符重载

    • 运算符重载基础
    • 算术与关系运算符重载
    • 赋值与移动运算符重载
    • 特殊运算符重载
  • 第7章 模板与泛型编程

    • 函数模板
    • 类模板
    • 模板特化与偏特化
    • 可变参数模板
    • 别名模板与模板模板参数
    • SFINAE 与类型萃取
    • 依赖名与 typename/template 关键字
  • 第8章 异常处理

    • 异常处理机制
    • noexcept 与异常安全
    • RAII 与异常安全实践
  • 第9章 内存管理与智能指针

    • 动态内存与内存分区
    • RAII 惯用法
    • unique_ptr
    • shared_ptr 与 weak_ptr
    • 内存管理最佳实践
  • 第10章 右值引用与移动语义

    • 右值引用与值类别深度解析
    • std::move 原理与使用
    • 完美转发与 std::forward
    • 移动语义性能对比与最佳实践
  • 第11章 STL容器

    • vector 深度剖析
    • deque 内部机制
    • list 与 forward_list
    • map 与 set 深度解析
    • unordered 容器与哈希原理
    • array 与 tuple
    • 容器适配器
    • 容器选择全景指南
  • 第12章 STL算法与迭代器

    • 迭代器体系全解
    • 非变异算法
    • 变异算法
    • 排序与二分算法
    • Lambda 与算法组合
    • std::random 随机数库
    • 自定义迭代器开发
  • 第13章 IO流与文件

    • 标准 IO 流
    • 格式化输出控制
    • 文件流操作
    • 字符串流
    • std::regex 正则表达式
  • 第14章 并发与多线程

    • thread 基础与线程管理
    • mutex 与 lock_guard
    • unique_lock 与 condition_variable
    • thread_local 线程局部存储
    • atomic 与内存序
    • future 与 async 异步编程
    • std::chrono 时间库
  • 第15章 现代C++新特性

    • 从 C++11 到 C++20 演进路线
    • C++14 关键新特性
    • C++17 关键新特性
    • C++20 核心特性速览
  • 第16章 面试考点与最佳实践

    • C++ 综合最佳实践清单
    • 高频面试题精讲
    • 多线程面试题与实战
    • 内存管理常见陷阱与排查
  • 附录

    • C++ 核心知识点
    • C++ 专业术语

thread 基础与线程管理

定义与作用

std::thread 是 C++11 引入的标准线程类,封装操作系统原生线程,提供统一的跨平台线程管理接口。

#include <thread>

std::thread t([]() { std::cout << "Hello from thread\n"; });
t.join();  // 等待线程结束

核心原理

线程生命周期

join vs detach

完整示例

示例一:飞翔科技并行日志分析

场景说明:李眉用多线程并行分析多个服务器日志文件。

#include <iostream>
#include <thread>
#include <vector>
#include <string>
#include <chrono>
#include <sstream>
#include <iomanip>

// 模拟单台服务器的日志分析
struct AnalysisResult {
    std::string serverName;
    int totalLines   = 0;
    int errorCount   = 0;
    int warnCount    = 0;
    double avgCpu    = 0.0;
    int duration_ms  = 0;
};

AnalysisResult analyzeServerLog(const std::string& serverName,
                                 int lineCount) {
    auto start = std::chrono::steady_clock::now();
    auto tid   = std::this_thread::get_id();

    // 模拟耗时分析
    int errors = 0, warns = 0;
    for (int i = 0; i < lineCount; ++i) {
        // 模拟 CPU 密集型工作
        volatile int x = 0;
        for (int j = 0; j < 1000; ++j) x += j;

        if (i % 100 == 0) ++errors;
        if (i % 50 == 0)  ++warns;
    }

    auto end = std::chrono::steady_clock::now();
    int ms = std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count();

    std::ostringstream oss;
    oss << "  [线程 " << tid << "] " << serverName << " 分析完成 ("
        << ms << "ms)\n";

    // 加锁输出避免交错(仅为演示)
    static std::mutex coutMutex;
    {
        std::lock_guard<std::mutex> lock(coutMutex);
        std::cout << oss.str() << std::flush;
    }

    return {serverName, lineCount, errors, warns, 0.0, ms};
}

int main() {
    std::cout << "=== 飞翔科技并行日志分析 ===\n";
    std::cout << "CPU 逻辑核心数: " << std::thread::hardware_concurrency() << "\n\n";

    std::vector<std::thread> threads;
    std::vector<AnalysisResult> results;

    // 使用 mutex 保护 results
    std::mutex resultMutex;

    auto startAll = std::chrono::steady_clock::now();

    // 启动多个线程分析不同服务器
    std::vector<std::pair<std::string, int>> servers = {
        {"Web-01",   5000},
        {"Web-02",   3000},
        {"DB-Master",8000},
        {"Cache-01", 2000},
        {"MQ-01",    4000},
        {"Log-01",   6000},
    };

    for (const auto& [name, lines] : servers) {
        threads.emplace_back([&results, &resultMutex, name, lines]() {
            auto r = analyzeServerLog(name, lines);
            {
                std::lock_guard<std::mutex> lock(resultMutex);
                results.push_back(r);
            }
        });
    }

    std::cout << "已启动 " << threads.size() << " 个线程\n";

    // join 所有线程
    for (auto& t : threads) {
        if (t.joinable()) t.join();
    }

    auto endAll = std::chrono::steady_clock::now();
    int totalMs = std::chrono::duration_cast<std::chrono::milliseconds>(endAll - startAll).count();

    std::cout << "\n=== 分析结果 ===\n";
    std::cout << std::left
              << std::setw(14) << "服务器"
              << std::setw(10) << "日志行数"
              << std::setw(10) << "错误数"
              << std::setw(10) << "警告数"
              << std::setw(10) << "耗时(ms)"
              << "\n";
    std::cout << std::string(54, '-') << "\n";

    int totalLines = 0, totalErrors = 0, totalWarns = 0;
    for (const auto& r : results) {
        std::cout << std::left
                  << std::setw(14) << r.serverName
                  << std::setw(10) << r.totalLines
                  << std::setw(10) << r.errorCount
                  << std::setw(10) << r.warnCount
                  << std::setw(10) << r.duration_ms
                  << "\n";
        totalLines  += r.totalLines;
        totalErrors += r.errorCount;
        totalWarns  += r.warnCount;
    }

    std::cout << std::string(54, '-') << "\n";
    std::cout << std::left
              << std::setw(14) << "合计"
              << std::setw(10) << totalLines
              << std::setw(10) << totalErrors
              << std::setw(10) << totalWarns
              << "\n";
    std::cout << "\n总耗时: " << totalMs << "ms\n";
    std::cout << "并行效率: 使用 " << threads.size()
              << " 个核心处理 " << totalLines
              << " 行日志\n";
}

预期输出:

=== 飞翔科技并行日志分析 ===
CPU 逻辑核心数: 16

已启动 6 个线程
  [线程 12345] Web-01 分析完成 (XXXms)
  [线程 12346] Web-02 分析完成 (XXXms)
  ...

=== 分析结果 ===
服务器         日志行数   错误数     警告数     耗时(ms)
------------------------------------------------------
Web-01         5000       50        100        XXX
Web-02         3000       30        60         XXX
...

总耗时: XXXms
并行效率: 使用 6 个核心处理 28000 行日志

逐段分析:

  • std::thread 构造时立即启动线程执行可调用对象
  • hardware_concurrency() 返回逻辑核心数,用于确定并行度
  • 必须 join() 或 detach(),否则析构时 std::terminate
  • std::mutex + lock_guard 保护共享 results 容器
  • this_thread::get_id() 获取当前线程 ID

示例二:detach 与后台线程

场景说明:大翔让飞翔科技的监控线程在后台持续运行。

#include <iostream>
#include <thread>
#include <atomic>
#include <chrono>

std::atomic<bool> running{true};

void backgroundMonitor() {
    std::cout << "[监控] 后台线程启动\n";

    int tick = 0;
    while (running.load(std::memory_order_relaxed)) {
        std::this_thread::sleep_for(std::chrono::seconds(1));
        ++tick;

        // 模拟指标采集
        if (tick % 5 == 0)
            std::cout << "[监控] 心跳 #" << tick << " - 系统正常\n";
    }

    std::cout << "[监控] 收到停止信号,安全退出 (共运行 "
              << tick << " 秒)\n";
}

int main() {
    std::cout << "=== 飞翔科技后台监控 ===\n\n";

    // 启动后台线程并 detach
    std::thread monitor(backgroundMonitor);
    monitor.detach();  // 分离——线程独立运行
    std::cout << "监控线程已分离,主线程继续...\n\n";

    // 主线程执行其他任务
    std::this_thread::sleep_for(std::chrono::seconds(3));
    std::cout << "[主线程] 处理业务请求...\n";
    std::this_thread::sleep_for(std::chrono::seconds(3));

    // 发送停止信号
    std::cout << "\n[主线程] 发送停止信号\n";
    running.store(false, std::memory_order_relaxed);

    // 给 detach 线程一些时间退出
    std::this_thread::sleep_for(std::chrono::seconds(2));
    std::cout << "[主线程] 程序结束\n";
}

预期输出:

=== 飞翔科技后台监控 ===

[监控] 后台线程启动
监控线程已分离,主线程继续...

[监控] 心跳 #5 - 系统正常
[监控] 心跳 #10 - 系统正常
[主线程] 处理业务请求...
[监控] 心跳 #15 - 系统正常

[主线程] 发送停止信号
[监控] 收到停止信号,安全退出 (共运行 17 秒)
[主线程] 程序结束

逐段分析:

  • detach() 后线程独立运行,thread 对象不再管理它
  • std::atomic<bool> 用于线程间安全通信
  • sleep_for 模拟定时任务
  • detach 线程必须在主线程结束前收到停止信号并自行退出

易错场景与面试考点

易错场景

1. 忘记 join 或 detach

void bad() {
    std::thread t([]() { std::cout << "work\n"; });
    // t 析构时 joinable() == true → std::terminate()!
}

2. detach 后访问已销毁对象

void bad() {
    int local = 42;
    std::thread t([&local]() {
        std::this_thread::sleep_for(std::chrono::seconds(1));
        std::cout << local;  // ❌ local 可能已销毁
    });
    t.detach();
}  // local 销毁,detach 线程还在运行

3. 异常导致未 join

void risky() {
    std::thread t(work);
    doSomethingThatMayThrow();  // 如果抛异常...
    t.join();                    // ❌ 永远不会执行
}
// 解决:使用 RAII 包装器或 try-catch

面试考点

考点要点
thread 构造传函数对象 + 参数,立即启动
join vs detachjoin 阻塞等待;detach 分离独立运行
joinable()检查线程是否可 join/detach
hardware_concurrency获取逻辑 CPU 核心数,用于并行度决策
线程生命周期构造→可join→join/detach→不可join
this_thread 命名空间get_id(), sleep_for(), sleep_until(), yield()
线程 IDstd:🧵:id 类型,可比较、可哈希、可输出
异常安全使用 RAII 包装(如 std::jthread C++20)
下一页
mutex 与 lock_guard