C++ std
多线程教程
理解多线程的概念
多线程是一种并发编程技术,它允许程序同时运行多个任务。每个线程共享同一进程的资源(如内存),但拥有独立的执行路径。多线程编程在现代 C++ 中变得更加便捷和安全,标准库提供了强大的多线程支持,包括线程创建、同步和管理。
多线程的优点
- 提高性能:充分利用多核 CPU 的并行计算能力。
- 异步操作:后台任务(如文件处理、网络通信)可以在不阻塞主线程的情况下运行。
- 简化复杂任务:将复杂任务分解为多个线程独立处理。
C++ 提供的多线程支持
C++11 开始标准库新增了 <thread>
模块,用于线程管理,并提供同步机制(如互斥锁、条件变量)。
1. C++ 多线程基础
1.1 创建线程
通过 std::thread
创建线程。线程可以执行:
- 函数。
- Lambda 表达式。
- 成员函数。
示例
#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 线程的生命周期
- 创建:通过
std::thread
创建新线程。 - 加入:
join()
:主线程等待子线程完成。detach()
:分离线程,子线程独立运行。
- 结束:线程完成任务或被终止。
示例:detach
和 join
#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 表达式作为线程函数
示例
#include <iostream>
#include <thread>
int main() {
std::thread t([] {
std::cout << "Hello from Lambda!" << std::endl;
});
t.join();
return 0;
}
1.4 传递参数到线程
通过 std::thread
构造函数将参数传递给线程函数。
示例
#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
)
示例:保护共享资源
#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
)
条件变量用于线程间通信和同步。
示例:生产者-消费者模型
#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 环境下编写一个多线程程序,该程序计算数组的部分和,并最终输出总和。
完整代码
#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 环境中编译和运行:
g++ -std=c++11 -pthread -o multithreading_demo multithreading_demo.cpp
./multithreading_demo
结果示例
Partial sum [0, 25) = 325
Partial sum [25, 50) = 950
Partial sum [50, 75) = 1575
Partial sum [75, 100) = 2200
Total sum: 5050
学习建议
- 理解线程的生命周期:掌握线程的创建、管理和结束。
- 同步机制:熟悉
std::mutex
和std::condition_variable
的使用。 - 多线程调试:在 Linux 中使用工具(如
gdb
)调试多线程程序。
通过这些内容,你可以编写高效的 C++ 多线程程序,并在实际项目中灵活运用!