C++之多线程(multi-thread)

news/2024/12/21 20:22:28/

理论基础

多线程编程是C++中一个重要而复杂的主题。下面是一些建议和步骤,帮助你入门多线程编程:

  1. 了解基础概念:

    线程和进程: 理解线程和进程的基本概念。
    并发和并行: 区分并发和并行的概念,了解它们在多线程编程中的应用。

  2. 学习C++11及以后的线程支持:

    C++11 引入了对多线程编程的支持,包括 std::thread 类等。
    学习如何创建、加入和分离线程。


#include <iostream>
#include <thread>void myFunction() {// 线程执行的函数std::cout << "Hello from thread!" << std::endl;
}int main() {// 创建线程并执行函数std::thread myThread(myFunction);// 等待线程结束myThread.join();return 0;
}
  1. 理解线程同步和互斥:

    互斥锁(Mutex): 学习如何使用 std::mutex 来保护共享资源,防止多个线程同时访问。
    条件变量(Condition Variable): 了解如何使用 std::condition_variable 实现线程间的协同。


#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>std::mutex mtx;
std::condition_variable cv;
bool ready = false;void worker() {std::unique_lock<std::mutex> lock(mtx);cv.wait(lock, []{ return ready; });// 线程执行的任务std::cout << "Worker thread is done." << std::endl;
}int main() {std::thread myThread(worker);// 准备工作完成后通知线程{std::lock_guard<std::mutex> lock(mtx);ready = true;}cv.notify_one();myThread.join();return 0;
}
  1. 学习原子操作:

    原子操作: 了解如何使用 std::atomic 类型来进行原子操作,避免数据竞争。


#include <iostream>
#include <thread>
#include <atomic>std::atomic<int> counter(0);void increment() {for (int i = 0; i < 1000000; ++i) {counter++;}
}int main() {std::thread t1(increment);std::thread t2(increment);t1.join();t2.join();std::cout << "Counter value: " << counter << std::endl;return 0;
}
  1. 阅读相关书籍和资料:

    《C++ Concurrency in Action》(作者:Anthony Williams):深入讲解C++中的并发编程。
    C++ Multithreading:一个较为详细的在线教程。

  2. 实践多线程编程:

    尝试编写简单的多线程程序,理解线程之间的交互和共享资源的问题。
    解决一些典型的多线程问题,例如生产者-消费者问题等。

  3. 进一步学习:

    了解更高级的主题,如并行算法、任务调度等。
    探索C++标准库中与并发相关的其他组件,如 std::async、std::future 等。

最后的测试实例

#include <iostream>
#include <vector>
#include <thread>
#include <mutex>
#include <chrono>
using namespace std;
std::mutex mtx;  // 互斥锁,用于保护共享资源
int sum = 0;     // 共享资源,存储数组的和// 计算数组的和的函数
void calculateSum(const std::vector<int>& numbers, int start, int end) {int localSum = 0;for (int i = start; i < end; ++i) {localSum += numbers[i];cout << "numbers =" << numbers[i] << endl;std::this_thread::sleep_for(std::chrono::milliseconds(10));}// 使用互斥锁保护对共享资源的访问std::lock_guard<std::mutex> lock(mtx);sum += localSum;cout << "sum =" << sum << endl;
}int main() {// 创建一个包含整数的数组std::vector<int> numbers = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};// 定义线程的数量const int numThreads = 2;// 计算每个线程的工作量const int chunkSize = numbers.size() / numThreads;// 创建线程数组std::vector<std::thread> threads;// 启动线程for (int i = 0; i < numThreads; ++i) {int start = i * chunkSize;int end = (i == numThreads - 1) ? numbers.size() : (i + 1) * chunkSize;threads.emplace_back(calculateSum, std::ref(numbers), start, end);cout << "num threads" << i << endl;}// 等待所有线程完成for (auto& thread : threads) {thread.join();}// 输出最终的结果std::cout << "Sum of the array: " << sum << std::endl;return 0;
}

http://www.ppmy.cn/news/1350046.html

相关文章

没更新的日子也在努力呀,布局2024!

文章目录 ⭐ 没更新的日子也在努力呀⭐ 近期的一个状态 - 已圆满⭐ 又到了2024的许愿时间了⭐ 开发者要如何去 "创富" ⭐ 没更新的日子也在努力呀 感觉很久没有更新视频了&#xff0c;好吧&#xff0c;其实真的很久没有更新短视频了。最近的一两个月真的太忙了&#…

第一章、APPium、android自动化

第一章、APPium、android自动化 第二章、android利用QPython环境调用APPium 环境搭建 1、android studio 配置SDK Manger 的sdk、ndk、adb 控制台输入 open -e /Users/shenjianbin/.bash_profile.save export ANDROID_SDK/Users/shenjianbin/Library/Android/sdk export PA…

OCP使用web console创建和构建应用

文章目录 环境登录创建project赋予查看权限部署第一个image检查pod扩展应用 部署一个Python应用连接数据库创建secret加载数据并显示国家公园地图 清理参考 环境 RHEL 9.3Red Hat OpenShift Local 2.32 登录 在 crc start 启动crc时&#xff0c;可以看到&#xff1a; .....…

ClickHouse--02--安装

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 安装官网 &#xff1b;[https://clickhouse.com/docs/zh/getting-started/install](https://clickhouse.com/docs/zh/getting-started/install)![在这里插入图片描述…

中国电子学会2020年9月份青少年软件编程Scratch图形化等级考试试卷三级真题(编程题)

编程题(共3题&#xff0c;共30分) 36.题目&#xff1a;魔术表演“开花” 1.准备工作 &#xff08;1&#xff09;将舞台设置为"Party"&#xff1b; &#xff08;2&#xff09;删除默认角色&#xff0c;自行绘制椭圆花瓣角色&#xff1b; &#xff08;3&#xf…

C++ | KMP算法模板

next数组初始化 char a[1000006];//原串 char p[1000006];//子串 int pmt[1000006];void getNext(int m){int j0;pmt[0]0;for(int i1;i<m;i){while(j>0 && p[i]!p[j])jpmt[j-1];if(p[i]p[j])j;pmt[i]j;} }以下实例基于上述getNext函数及数据结构执行&#xff1a…

Flink从入门到实践(三):数据实时采集 - Flink MySQL CDC

文章目录 系列文章索引一、概述1、版本匹配2、导包 二、编码实现1、基本使用2、更多配置3、自定义序列化器4、Flink SQL方式 三、踩坑1、The MySQL server has a timezone offset (0 seconds ahead of UTC) which does not match the configured timezone Asia/Shanghai. 参考资…

【JVM篇】ThreadLocal中为什么要使用弱引用

文章目录 &#x1f354;ThreadLocal中为什么要使用弱引用⭐总结 &#x1f354;ThreadLocal中为什么要使用弱引用 ThreadLocal可以在线程中存放线程的本地变量&#xff0c;保证数据的线程安全 ThreadLocal是这样子保存对象的&#xff1a; 在每个线程中&#xff0c;存放了一个…