<C++学习>C++ std 多线程教程

C++ std 多线程教程


理解多线程的概念

多线程是一种并发编程技术,它允许程序同时运行多个任务。每个线程共享同一进程的资源(如内存),但拥有独立的执行路径。多线程编程在现代 C++ 中变得更加便捷和安全,标准库提供了强大的多线程支持,包括线程创建、同步和管理。

多线程的优点
  1. 提高性能:充分利用多核 CPU 的并行计算能力。
  2. 异步操作:后台任务(如文件处理、网络通信)可以在不阻塞主线程的情况下运行。
  3. 简化复杂任务:将复杂任务分解为多个线程独立处理。
C++ 提供的多线程支持

C++11 开始标准库新增了 <thread> 模块,用于线程管理,并提供同步机制(如互斥锁、条件变量)。


1. C++ 多线程基础

1.1 创建线程

通过 std::thread 创建线程。线程可以执行:

  1. 函数。
  2. Lambda 表达式。
  3. 成员函数。
示例
cpp 复制代码
#include <iostream>
#include <thread>

void printMessage() {
    std::cout << "Hello from thread!" << std::endl;
}

int main() {
    std::thread t(printMessage); // 创建线程 t
    t.join(); // 等待线程 t 执行完毕
    return 0;
}

1.2 线程的生命周期

  1. 创建 :通过 std::thread 创建新线程。
  2. 加入
    • join():主线程等待子线程完成。
    • detach():分离线程,子线程独立运行。
  3. 结束:线程完成任务或被终止。
示例:detachjoin
cpp 复制代码
#include <iostream>
#include <thread>

void detachedThread() {
    std::cout << "Detached thread running..." << std::endl;
}

void joinedThread() {
    std::cout << "Joined thread running..." << std::endl;
}

int main() {
    std::thread t1(detachedThread);
    t1.detach(); // 分离线程,主线程不再管理它

    std::thread t2(joinedThread);
    t2.join(); // 主线程等待 t2 完成

    std::cout << "Main thread finished." << std::endl;
    return 0;
}

1.3 Lambda 表达式作为线程函数

示例
cpp 复制代码
#include <iostream>
#include <thread>

int main() {
    std::thread t([] {
        std::cout << "Hello from Lambda!" << std::endl;
    });
    t.join();
    return 0;
}

1.4 传递参数到线程

通过 std::thread 构造函数将参数传递给线程函数。

示例
cpp 复制代码
#include <iostream>
#include <thread>

void printNumbers(int n, const std::string& message) {
    for (int i = 0; i < n; i++) {
        std::cout << message << " " << i << std::endl;
    }
}

int main() {
    std::thread t(printNumbers, 5, "Count"); // 传递参数 5 和 "Count"
    t.join();
    return 0;
}

2. 线程同步

多线程共享资源时,可能会导致数据竞争(race condition)。C++ 提供了多种同步机制来解决这些问题。


2.1 互斥锁(std::mutex

示例:保护共享资源
cpp 复制代码
#include <iostream>
#include <thread>
#include <mutex>

std::mutex mtx; // 定义一个互斥锁
int counter = 0;

void increment() {
    for (int i = 0; i < 100; i++) {
        std::lock_guard<std::mutex> lock(mtx); // 自动加锁和解锁
        counter++;
    }
}

int main() {
    std::thread t1(increment);
    std::thread t2(increment);

    t1.join();
    t2.join();

    std::cout << "Final counter value: " << counter << std::endl;
    return 0;
}

2.2 条件变量(std::condition_variable

条件变量用于线程间通信和同步。

示例:生产者-消费者模型
cpp 复制代码
#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <queue>

std::queue<int> q;
std::mutex mtx;
std::condition_variable cv;

void producer() {
    for (int i = 0; i < 10; i++) {
        std::unique_lock<std::mutex> lock(mtx);
        q.push(i);
        std::cout << "Produced: " << i << std::endl;
        cv.notify_one(); // 通知消费者
    }
}

void consumer() {
    for (int i = 0; i < 10; i++) {
        std::unique_lock<std::mutex> lock(mtx);
        cv.wait(lock, [] { return !q.empty(); }); // 等待队列非空
        int item = q.front();
        q.pop();
        std::cout << "Consumed: " << item << std::endl;
    }
}

int main() {
    std::thread t1(producer);
    std::thread t2(consumer);

    t1.join();
    t2.join();
    return 0;
}

3. 多线程的Linux Demo

以下示例演示了如何在 Linux 环境下编写一个多线程程序,该程序计算数组的部分和,并最终输出总和。

完整代码
cpp 复制代码
#include <iostream>
#include <thread>
#include <vector>
#include <numeric>
#include <functional>

void partialSum(const std::vector<int>& data, int start, int end, int& result) {
    result = std::accumulate(data.begin() + start, data.begin() + end, 0);
    std::cout << "Partial sum [" << start << ", " << end << ") = " << result << std::endl;
}

int main() {
    const int size = 100;
    std::vector<int> data(size);
    std::iota(data.begin(), data.end(), 1); // 初始化数组 [1, 2, ..., 100]

    int numThreads = 4;
    int blockSize = size / numThreads;
    std::vector<std::thread> threads;
    std::vector<int> results(numThreads);

    // 启动线程
    for (int i = 0; i < numThreads; i++) {
        int start = i * blockSize;
        int end = (i == numThreads - 1) ? size : start + blockSize;
        threads.emplace_back(partialSum, std::cref(data), start, end, std::ref(results[i]));
    }

    // 等待线程完成
    for (auto& t : threads) {
        t.join();
    }

    // 计算总和
    int totalSum = std::accumulate(results.begin(), results.end(), 0);
    std::cout << "Total sum: " << totalSum << std::endl;

    return 0;
}

运行示例

在 Linux 环境中编译和运行:

bash 复制代码
g++ -std=c++11 -pthread -o multithreading_demo multithreading_demo.cpp
./multithreading_demo

结果示例

plaintext 复制代码
Partial sum [0, 25) = 325
Partial sum [25, 50) = 950
Partial sum [50, 75) = 1575
Partial sum [75, 100) = 2200
Total sum: 5050

学习建议

  1. 理解线程的生命周期:掌握线程的创建、管理和结束。
  2. 同步机制 :熟悉 std::mutexstd::condition_variable 的使用。
  3. 多线程调试 :在 Linux 中使用工具(如 gdb)调试多线程程序。

通过这些内容,你可以编写高效的 C++ 多线程程序,并在实际项目中灵活运用!

相关推荐
计算机小混子1 小时前
C++实现设计模式---访问者模式 (Visitor)
c++·设计模式·访问者模式
佐咖1 小时前
C++STL中常用的排序算法:sort、random_shuffle、merge和reverse(附C++代码)
开发语言·c++·排序算法
IOT-Power2 小时前
<C++学习>C++的 Boost 基础知识
c++
夕泠爱吃糖2 小时前
选择排序&冒泡排序
数据结构·c++·算法
~yY…s<#>2 小时前
5种IO模型
android·linux·服务器·c语言·c++
ExRoc2 小时前
蓝桥杯真题 - 最大开支 - 题解
c++·算法·蓝桥杯
过过过呀Glik3 小时前
在 Ubuntu 中安装 C++ 版本的 Protocol Buffers
linux·c++·ubuntu·protocol
计算机小混子3 小时前
C++实现设计模式---单例模式 (Singleton)
开发语言·c++·单例模式
计算机小混子3 小时前
C++实现设计模式---工厂方法模式 (Factory Method)
c++·设计模式·工厂方法模式