![[C++]多线程](http://pic.xiahunao.cn/yaotu/[C++]多线程)
C 中实现高并发计算核心是通过充分利用多核 CPU、优化资源调度、减少阻塞等方式提升并行处理能力。以下是常见的实现方法及示例一、多线程基于 C 标准库利用std::thread创建线程结合同步机制互斥锁、条件变量等实现并发。1. 基础多线程cpp#include thread #include vector #include iostream void task(int id) { // 并行执行的任务 std::cout Thread id running\n; } int main() { const int num_threads 8; // 根据CPU核心数调整 std::vectorstd::thread threads; for (int i 0; i num_threads; i) { threads.emplace_back(task, i); // 创建线程并执行任务 } for (auto t : threads) { t.join(); // 等待所有线程完成 } return 0; }2. 线程池避免频繁创建销毁线程cpp#include thread #include vector #include queue #include mutex #include condition_variable #include functional class ThreadPool { public: ThreadPool(int num_threads) { for (int i 0; i num_threads; i) { workers.emplace_back([this] { while (true) { std::functionvoid() task; { std::unique_lockstd::mutex lock(mtx); cv.wait(lock, [this] { return stop || !tasks.empty(); }); if (stop tasks.empty()) return; task std::move(tasks.front()); tasks.pop(); } task(); // 执行任务 } }); } } template typename F void enqueue(F f) { { std::unique_lockstd::mutex lock(mtx); tasks.emplace(std::forwardF(f)); } cv.notify_one(); // 唤醒一个线程执行任务 } ~ThreadPool() { { std::unique_lockstd::mutex lock(mtx); stop true; } cv.notify_all(); for (auto w : workers) { w.join(); } } private: std::vectorstd::thread workers; std::queuestd::functionvoid() tasks; std::mutex mtx; std::condition_variable cv; bool stop false; }; // 使用示例 int main() { ThreadPool pool(4); for (int i 0; i 10; i) { pool.enqueue([i] { std::cout Task i executed\n; }); } return 0; }二、并行算法C17 及以上利用std::execution策略实现算法的并行化如std::for_each、std::transform。cpp#include vector #include algorithm #include execution #include iostream int main() { std::vectorint data(1000000, 1); // 并行计算每个元素乘以2 std::for_each(std::execution::par, data.begin(), data.end(), [](int x) { x * 2; }); std::cout Parallel computation done\n; return 0; }说明std::execution::par表示并行执行底层自动利用多线程需编译器支持如 GCC 9、Clang 10。三、OpenMP共享内存并行通过编译制导指令#pragma omp实现简单高效的并行。cpp#include iostream #include vector #include omp.h int main() { const int n 1000000; std::vectorint a(n, 1), b(n, 2), c(n); // 并行计算c[i] a[i] b[i] #pragma omp parallel for num_threads(8) for (int i 0; i n; i) { c[i] a[i] b[i]; } std::cout OpenMP parallel done\n; return 0; }编译需添加编译选项如g -fopenmp。四、MPI分布式内存并行适用于多机集群或分布式系统通过消息传递实现并发。cpp#include mpi.h #include iostream int main(int argc, char**argv) { MPI_Init(argc, argv); int rank, size; MPI_Comm_rank(MPI_COMM_WORLD, rank); // 当前进程ID MPI_Comm_size(MPI_COMM_WORLD, size); // 总进程数 if (rank 0) { // 主进程发送数据 int data 100; MPI_Send(data, 1, MPI_INT, 1, 0, MPI_COMM_WORLD); } else if (rank 1) { // 从进程接收数据 int data; MPI_Recv(data, 1, MPI_INT, 0, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE); std::cout Received: data \n; } MPI_Finalize(); return 0; }编译需 MPI 库如 OpenMPI编译命令mpic -o mpi_demo mpi_demo.cpp。五、C 协程C20 及以上轻量级并发适合 I/O 密集型任务减少线程切换开销。cpp#include coroutine #include iostream #include future struct Task { struct promise_type { std::futureint fut; std::promiseint prom; Task get_return_object() { return {std::coroutine_handlepromise_type::from_promise(*this)}; } std::suspend_never initial_suspend() { return {}; } std::suspend_never final_suspend() noexcept { return {}; } void return_value(int val) { prom.set_value(val); } void unhandled_exception() { prom.set_exception(std::current_exception()); } }; std::coroutine_handlepromise_type h; Task(std::coroutine_handlepromise_type h) : h(h) {} ~Task() { h.destroy(); } int get() { return h.promise().prom.get_future().get(); } }; Task compute() { co_return 42; // 协程任务 } int main() { Task task compute(); std::cout Result: task.get() \n; return 0; }说明协程更适合高并发 I/O 场景如网络请求需编译器支持如 GCC 10、Clang 15。六、GPU 加速CUDA/OpenCL利用 GPU 的大规模并行计算能力适用于计算密集型任务。CUDA 示例NVIDIA GPUcpp#include iostream #include vector __global__ void add(int* a, int* b, int* c, int n) { int i blockIdx.x * blockDim.x threadIdx.x; if (i n) { c[i] a[i] b[i]; } } int main() { const int n 1024; std::vectorint a(n, 1), b(n, 2), c(n); int *d_a, *d_b, *d_c; cudaMalloc(d_a, n * sizeof(int)); cudaMalloc(d_b, n * sizeof(int)); cudaMalloc(d_c, n * sizeof(int)); cudaMemcpy(d_a, a.data(), n * sizeof(int), cudaMemcpyHostToDevice); cudaMemcpy(d_b, b.data(), n * sizeof(int), cudaMemcpyHostToDevice); // 启动GPU核函数1024线程 add1, n(d_a, d_b, d_c, n); cudaMemcpy(c.data(), d_c, n * sizeof(int), cudaMemcpyDeviceToHost); cudaFree(d_a); cudaFree(d_b); cudaFree(d_c); std::cout GPU computation done\n; return 0; }七、其他优化手段无锁编程使用std::atomic避免锁开销适合简单数据竞争场景。cpp#include atomic #include thread std::atomicint counter 0; void increment() { for (int i 0; i 10000; i) { counter; // 原子操作无锁 } } int main() { std::thread t1(increment), t2(increment); t1.join(); t2.join(); std::cout Counter: counter \n; // 预期20000 return 0; }数据分片将大任务拆分为小块分配给不同线程 / 进程减少竞争。异步 I/O使用std::async或操作系统异步 API如IOCP、epoll处理 I/O避免阻塞。cpp#include future #include iostream int compute() { return 42; } int main() { auto fut std::async(std::launch::async, compute); // 异步执行 std::cout Result: fut.get() \n; return 0; }总结计算密集型优先使用多线程、线程池、OpenMP、GPU 加速。I/O 密集型优先使用协程、异步 I/O、事件驱动如 libevent。分布式场景使用 MPI 或分布式框架如 Spark。优化核心减少锁竞争、合理利用缓存、避免资源浪费如线程池复用线程。你的表述中似乎将不同的内容混杂在一起了前面提到“从你的问题来看你可能是想了解在Qt环境下如何处理高并发相关的内容”但实际上用户当前的问题是围绕“高并发计算的实现”展开且之前的对话是关于Qt调试中出现的“command not found”错误可能是在梳理过程中出现了混淆。 首先针对“高并发计算的实现”用户提供的各种C方法是比较全面的包括多线程、线程池、并行算法、OpenMP、MPI、协程、GPU加速等这些都是C中实现高并发的重要手段。 在实际应用中选择哪种方法确实需要根据具体场景来决定 - 对于普通的多线程任务线程池是比较常用的能避免线程频繁创建销毁的开销。 - 数据并行处理时C17的并行算法很方便无需手动管理线程。 - 共享内存环境下的循环级并行OpenMP简单易用。 - 分布式系统中MPI是主流选择。 - I/O密集型任务协程能显著提升性能。 - 计算密集且高度并行的任务GPU加速效果明显。 另外无锁编程、任务拆分、异步I/O等优化手段往往会结合上述方法一起使用以进一步提升并发性能。 如果是针对之前提到的Qt中“command not found”错误需要检查环境变量配置、程序是否正确安装等但当前用户的核心需求是了解高并发计算的实现所以重点应放在对各种高并发方法的解读和应用场景分析上。在 C 中通过建立子类来实现多线程是一种常见方式核心是让子类继承线程类如 C 标准库的std::thread或 Qt 中的QThread并重写相关方法来定义线程任务。这种方式能更好地封装线程的行为使代码结构更清晰。以 C 标准库std::thread为例通过子类封装线程逻辑cpp#include thread #include iostream // 自定义线程子类封装线程任务 class MyThread : public std::thread { public: // 构造函数接收任务函数 MyThread(void (*task)()) : std::thread(task) {} // 也可以通过重写或绑定成员函数作为任务 void run() { std::cout 子线程运行中...\n; // 线程具体逻辑 } }; // 线程任务函数 void threadTask() { std::cout 线程任务执行\n; } int main() { // 通过子类创建线程传入任务函数 MyThread t(threadTask); t.join(); // 等待线程结束 return 0; }以 Qt 的QThread为例更典型的子类化用法在 Qt 中QThread的子类化是常用方式通过重写run()函数定义线程任务cpp#include QThread #include QDebug class MyThread : public QThread { protected: // 重写run()方法定义线程具体执行的任务 void run() override { qDebug() 子线程开始执行; // 线程任务逻辑如循环处理数据、I/O操作等 for (int i 0; i 5; i) { qDebug() 子线程计数 i; msleep(500); // 模拟耗时操作 } qDebug() 子线程结束; } }; // 使用方式 int main(int argc, char *argv[]) { QCoreApplication app(argc, argv); MyThread thread; thread.start(); // 启动线程会自动调用run() thread.wait(); // 等待线程完成 return app.exec(); }子类实现多线程的优势封装性好将线程的任务逻辑封装在子类中与主线程代码分离结构更清晰便于维护。扩展性强可以在子类中添加成员变量或方法存储线程相关的状态如任务进度、错误信息等增强线程的功能。适配框架在 Qt 等框架中QThread的子类化是官方推荐的方式能更好地与框架的信号槽等机制结合处理线程间通信。这种方式特别适合任务逻辑相对固定的场景通过子类复用线程行为同时保持代码的模块化。