当前位置: 首页 > news >正文

C++ 之多线程相关总结

C++ 之多线程相关总结

1.多线程相关基础知识

1.1 线程的创建和管理

1. std::thread 类:

用于创建和管理线程。通过将可调用对象(如函数、函数对象、lambda 表达式)作为参数传递给 std::thread 的构造函数,可以创建一个新的线程。

  • join() 方法会阻塞当前线程,直到被调用的线程执行完毕。如果不调用 join()detach(),程序会在 std::thread 对象析构时终止程序,因为会调用 std::terminate()
  • detach() 方法允许线程独立运行,与主线程分离,不再被 std::thread 对象管理,它会继续在后台执行直至完成或程序结束。
#include <iostream>
#include <thread>void threadFunction() {std::cout << "Thread function running." << std::endl;
}int main() {std::thread t(threadFunction); // 创建一个新的线程,执行 threadFunctiont.join(); // 等待线程结束return 0;
}
2. 线程函数:

可以是普通函数、成员函数、函数对象或 lambda 表达式。

#include <iostream>
#include <thread>class MyClass {
public:void memberFunction() {std::cout << "Member function running in thread." << std::endl;}
};int main() {MyClass obj;std::thread t(&MyClass::memberFunction, &obj); // 调用成员函数t.join();return 0;
}

1.2 线程同步

1.互斥量(Mutex):
  • std::mutex 提供了基本的互斥机制,用于保护共享数据,防止多个线程同时访问。
#include <iostream>
#include <thread>
#include <mutex>std::mutex mtx;void printMessage(const std::string& message) {std::lock_guard<std::mutex> lock(mtx); // 自动加锁和解锁std::cout << message << std::endl;
}int main() {std::thread t1(printMessage, "Hello from thread 1");std::thread t2(printMessage, "Hello from thread 2");t1.join();t2.join();return 0;
}
  • std::lock_guard 是一个 RAII 类,在构造时自动锁定互斥量,在析构时自动解锁,确保正确的锁定和解锁操作。
  • std::unique_lock 提供了更灵活的锁定方式,可以手动加锁、解锁,支持延迟锁定和所有权转移。
2.条件变量(Condition Variables):
  • std::condition_variable 允许线程等待某些条件的发生。
#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <queue>std::mutex mtx;
std::condition_variable cv;
std::queue<int> dataQueue;void producer() {for (int i = 0; i < 10; ++i) {std::this_thread::sleep_for(std::chrono::milliseconds(100));std::unique_lock<std::mutex> lock(mtx);dataQueue.push(i);std::cout << "Produced: " << i << std::endl;cv.notify_one(); // 通知一个等待的线程}
}void consumer() {while (true) {std::unique_lock<std::mutex> lock(mtx);cv.wait(lock, []{ return!dataQueue.empty(); }); // 等待条件满足int data = dataQueue.front();dataQueue.pop();lock.unlock();std::cout << "Consumed: " << data << std::endl;if (data == 9) break;}
}int main() {std::thread t1(producer);std::thread t2(consumer);t1.join();t2.join();return 0;
}
  • cv.wait() 会释放锁并等待条件变量被通知,一旦收到通知,它会重新获取锁。
3. 原子操作
  • std::atomic 模板类提供了原子操作,确保操作的不可分割性,避免数据竞争。
#include <iostream>
#include <thread>
#include <atomic>std::atomic<int> counter(0);void increment() {for (int i = 0; i < 1000; ++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.3 线程间通信

1.共享数据:
  • 多个线程可以通过共享数据进行通信,但需要使用互斥量或其他同步机制来保护数据。
  • 避免死锁,如避免多个线程以不同顺序获取多个锁。
2.消息传递:
  • 使用 std::promisestd::future 可以实现线程间的单向消息传递。
#include <iostream>
#include <thread>
#include <future>int factorial(int n) {int result = 1;for (int i = 1; i <= n; ++i) {result *= i;}return result;
}int main() {std::promise<int> prom;std::future<int> fut = prom.get_future();std::thread t([&prom]() {int result = factorial(5);prom.set_value(result);});std::cout << "Factorial result: " << fut.get() << std::endl;t.join();return 0;
}

1.4 高级线程工具

1. std::async 和 std::future:
  • std::async 可以异步执行函数,并返回一个 std::future 对象。
#include <iostream>
#include <future>int add(int a, int b) {return a + b;
}int main() {std::future<int> result = std::async(std::launch::async, add, 3, 4);std::cout << "Sum: " << result.get() << std::endl;return 0;
}
  • std::launch::async 表示函数会在另一个线程中立即执行,std::launch::deferred 表示延迟执行,直到调用 get() 时才在调用线程中执行。
2. std::packaged_task:
  • 包装可调用对象,允许将其作为任务传递,并通过 std::future 获取结果。
#include <iostream>
#include <thread>
#include <future>int main() {std::packaged_task<int(int, int)> task(add);std::future<int> result = task.get_future();std::thread t(std::move(task), 3, 4);std::cout << "Sum: " << result.get() << std::endl;t.join();return 0;
}

2. 线程的使用:创建及管理

1.类内创建线程

  • 可以通过成员函数或者析构函数初始化或者创建线程,通过析构函数关闭/销毁线程
#include <iostream>
#include <thread>
#include <atomic>
#include <chrono>class ThreadedClass {
private:std::thread workerThread;std::atomic<bool> stopFlag;// 线程函数void workerFunction() {while (!stopFlag) {std::cout << "Thread is running..." << std::endl;std::this_thread::sleep_for(std::chrono::seconds(1));}std::cout << "Thread is stopping..." << std::endl;}
public:ThreadedClass() : stopFlag(false) {// 启动线程workerThread = std::thread(&ThreadedClass::workerFunction, this);}~ThreadedClass() {// 设置停止标志stopFlag = true;if (workerThread.joinable()) {// 等待线程结束workerThread.join();}}
};int main() {ThreadedClass obj;// 让程序运行一段时间,以便观察线程的行为std::this_thread::sleep_for(std::chrono::seconds(5));return 0;
}

2. 函数内部创建线程

  • 单独执行某个函数或者某个类的成员函数
#include <iostream>
#include <thread>
#include <chrono>class MyClass {
public:// 类中的函数,将在新线程中执行void classFunction() {for (int i = 0; i < 5; ++i) {std::cout << "Class function running, iteration: " << i << std::endl;std::this_thread::sleep_for(std::chrono::seconds(1));}}
};// 主函数,在其中创建线程执行类的函数
void mainFunction() {std::cout << "Main function starts." << std::endl;MyClass obj;// 创建一个新线程执行类的成员函数std::thread t(&MyClass::classFunction, &obj);// 主线程继续执行自己的任务for (int i = 0; i < 3; ++i) {std::cout << "Main function running, iteration: " << i << std::endl;std::this_thread::sleep_for(std::chrono::seconds(1));}// 等待新线程执行完毕t.join();std::cout << "Main function ends." << std::endl;
}// 函数将在新线程中执行
void newThreadFunction() {for (int i = 0; i < 5; ++i) {std::cout << "New thread: " << i << std::endl;std::this_thread::sleep_for(std::chrono::seconds(1));}
}int main() {mainFunction();//or// 创建一个新线程std::thread newThread(newThreadFunction);// 主线程继续执行自己的任务for (int i = 0; i < 3; ++i) {std::cout << "Main thread: " << i << std::endl;std::this_thread::sleep_for(std::chrono::seconds(1));}// 等待新线程执行完成newThread.join();return 0;
}

----更新中。。。。。

相关文章:

C++ 之多线程相关总结

C 之多线程相关总结 1.多线程相关基础知识 1.1 线程的创建和管理 1. std::thread 类&#xff1a; 用于创建和管理线程。通过将可调用对象&#xff08;如函数、函数对象、lambda 表达式&#xff09;作为参数传递给 std::thread 的构造函数&#xff0c;可以创建一个新的线程。…...

EF Core全局查询筛选器

目录 概述 用法 添加全局查询筛选器 禁用全局查询筛选器 概述 全局查询筛选器&#xff1a;EF Core 会自动将这个查询筛选器应用于涉及这个实体类型的所有 LINQ 查询。 场景&#xff1a;软删除、多租户。 什么是软删除&#xff1f; 逻辑删除&#xff0c;并不是真正地从数…...

【开源免费】基于SpringBoot+Vue.JS欢迪迈手机商城(JAVA毕业设计)

本文项目编号 T 141 &#xff0c;文末自助获取源码 \color{red}{T141&#xff0c;文末自助获取源码} T141&#xff0c;文末自助获取源码 目录 一、系统介绍二、数据库设计三、配套教程3.1 启动教程3.2 讲解视频3.3 二次开发教程 四、功能截图五、文案资料5.1 选题背景5.2 国内…...

Objective-C语言的数据库交互

Objective-C语言的数据库交互 引言 在现代应用程序开发过程中&#xff0c;数据库在数据存储和管理方面起着至关重要的作用。对于iOS应用开发者而言&#xff0c;掌握如何在Objective-C中与数据库交互显得尤为重要。本文将全面探讨Objective-C的数据库交互&#xff0c;包括SQLi…...

基于 Spring Boot 和 Vue.js 的全栈购物平台开发实践

在现代 Web 开发中&#xff0c;前后端分离的架构已经成为主流。本文将分享如何使用 Spring Boot 和 Vue.js构建一个全栈购物平台&#xff0c;涵盖从后端 API 开发到前端页面实现的完整流程。 1. 技术栈介绍 后端技术栈 JDK 1.8&#xff1a;稳定且广泛使用的 Java 版本。 Spring…...

笔记(数据运营方向)

以下是一些在工作过程中的小笔记&#xff0c;写的比较杂乱&#xff0c;后续再进行分类~ 1、掌握sql窗口函数 窗口函数又名开窗函数&#xff0c;属于分析函数的一种。用于解决复杂报表统计需求的功能强大的函数。窗口函数用于计算基于组的某种聚合值&#xff0c;它和聚合函数的…...

qt vs ios开发应用环境搭建和上架商店的记录

qt 下载链接如下 https://download.qt.io/new_archive/qt/5.14/5.14.2/qt-opensource-mac-x64-5.14.2.dmg 安装选项全勾选就行&#xff0c;这里特别说明下qt5.14.2/qml qt5.14.2对qml支持还算成熟&#xff0c;但很多特性还得qt6才行&#xff0c;这里用qt5.14.2主要是考虑到服…...

[cg] glDrawBuffers MRT的应用

glDrawBuffers 是 OpenGL 中的一个函数&#xff0c;用于指定渲染结果输出到哪些颜色缓冲区。它通常在多渲染目标&#xff08;MRT, Multiple Render Targets&#xff09;中使用&#xff0c;允许一个渲染操作同时将结果输出到多个颜色缓冲区&#xff0c;而不是默认情况下的单个颜…...

IO模型与NIO基础二

抽象基类之二 FilterInputStream FilterInputStream 的作用是用来“封装其它的输入流&#xff0c;并为它们提供额外的功能”。 它的常用的子类有BufferedInputStream和DataInputStream。 (1) BufferedInputStream的作用就是为“输入流提供缓冲功能&#xff0c;以及mark()和res…...

【设计模式】 单例模式(单例模式哪几种实现,如何保证线程安全,反射破坏单例模式)

单例模式 作用&#xff1a;单例模式的核心是保证一个类只有一个实例&#xff0c;并且提供一个访问实例的全局访问点。 实现方式优缺点饿汉式线程安全&#xff0c;调用效率高 &#xff0c;但是不能延迟加载懒汉式线程安全&#xff0c;调用效率不高&#xff0c;能延迟加载双重检…...

T-SQL语言的数据库交互

T-SQL语言的数据库交互 引言 随着信息技术的不断发展&#xff0c;数据库在各个行业中扮演着越来越重要的角色。数据库的有效管理和优化对于企业的数据安全、效率提升和决策支持至关重要。T-SQL&#xff08;Transact-SQL&#xff09;作为微软SQL Server的重要扩展语言&#xf…...

【Linux系统】Ext系列磁盘文件系统二:引入文件系统(续篇)

inode 和 block 的映射 该博文中有详细解释&#xff1a;【Linux系统】inode 和 block 的映射原理 目录与文件名 这里有几个问题&#xff1a; 问题一&#xff1a; 我们访问文件&#xff0c;都是用的文件名&#xff0c;没用过 inode 号啊&#xff1f; 之前总是说可以通过一个…...

慧集通(DataLinkX)iPaaS集成平台-业务建模之域

通过左侧导航菜单〖业务建模〗→〖域〗&#xff0c;进入该界面&#xff1b;在该界面可以查看到系统中已存在的域列表。 新建域 在慧集通平台中进入【业务建模】的【域】页面&#xff0c;点击【新建】按钮进入新建页面&#xff1b;输入编码&#xff0c;名称、模块以及对应数据类…...

【机器学习实战】kaggle 欺诈检测---使用生成对抗网络(GAN)解决欺诈数据中正负样本极度不平衡问题

【机器学习实战】kaggle 欺诈检测---如何解决欺诈数据中正负样本极度不平衡问题https://blog.csdn.net/2302_79308082/article/details/145177242 本篇文章是基于上次文章中提到的对抗生成网络&#xff0c;通过对抗生成网络生成少数类样本&#xff0c;平衡欺诈数据中正类样本极…...

android wifi framework与wpa_supplicant的交互

android frmework直接与wpa_supplicant进行交互&#xff0c;使用aidl或者hidl 二、事件 framework注册事件的地方&#xff1a; packages/modules/Wifi/service/java/com/android/server/wifi/SupplicantStaIfaceCallbackImpl.java class SupplicantStaIfaceCallbackImpl exte…...

初学stm32 --- flash模仿eeprom

目录 STM32内部FLASH简介 内部FLASH构成&#xff08;F1&#xff09; FLASH读写过程&#xff08;F1&#xff09; 闪存的读取 闪存的写入 内部FLASH构成&#xff08;F4 / F7 / H7&#xff09; FLASH读写过程&#xff08;F4 / F7 / H7&#xff09; 闪存的读取 闪存的写入 …...

使用C语言实现栈的插入、删除和排序操作

栈是一种后进先出(LIFO, Last In First Out)的数据结构,这意味着最后插入的元素最先被删除。在C语言中,我们可以通过数组或链表来实现栈。本文将使用数组来实现一个简单的栈,并提供插入(push)、删除(pop)以及排序(这里采用一种简单的排序方法,例如冒泡排序)的操作示…...

C语言程序环境和预处理详解

本章重点&#xff1a; 程序的翻译环境 程序的执行环境 详解&#xff1a;C语言程序的编译链接 预定义符号介绍 预处理指令 #define 宏和函数的对比 预处理操作符#和##的介绍 命令定义 预处理指令 #include 预处理指令 #undef 条件编译 程序的翻译环境和执行环…...

基于机器学习随机森林算法的个人职业预测研究

1.背景调研 随着信息技术的飞速发展&#xff0c;特别是大数据和云计算技术的广泛应用&#xff0c;各行各业都积累了大量的数据。这些数据中蕴含着丰富的信息和模式&#xff0c;为利用机器学习进行职业预测提供了可能。机器学习算法的不断进步&#xff0c;如深度学习、强化学习等…...

三种文本相似计算方法:规则、向量与大模型裁判

文本相似计算 项目背景 目前有众多工作需要评估字符串之间的相似(相关)程度&#xff1a;  比如&#xff0c;RAG 智能问答系统文本召回阶段需要计算用户文本与文本库内文本的相似分数&#xff0c;返回前TopK个候选文本。  在评估大模型生成的文本阶段&#xff0c;也需要评估…...

龙虎榜——20250610

上证指数放量收阴线&#xff0c;个股多数下跌&#xff0c;盘中受消息影响大幅波动。 深证指数放量收阴线形成顶分型&#xff0c;指数短线有调整的需求&#xff0c;大概需要一两天。 2025年6月10日龙虎榜行业方向分析 1. 金融科技 代表标的&#xff1a;御银股份、雄帝科技 驱动…...

日语AI面试高效通关秘籍:专业解读与青柚面试智能助攻

在如今就业市场竞争日益激烈的背景下&#xff0c;越来越多的求职者将目光投向了日本及中日双语岗位。但是&#xff0c;一场日语面试往往让许多人感到步履维艰。你是否也曾因为面试官抛出的“刁钻问题”而心生畏惧&#xff1f;面对生疏的日语交流环境&#xff0c;即便提前恶补了…...

【Python】 -- 趣味代码 - 小恐龙游戏

文章目录 文章目录 00 小恐龙游戏程序设计框架代码结构和功能游戏流程总结01 小恐龙游戏程序设计02 百度网盘地址00 小恐龙游戏程序设计框架 这段代码是一个基于 Pygame 的简易跑酷游戏的完整实现,玩家控制一个角色(龙)躲避障碍物(仙人掌和乌鸦)。以下是代码的详细介绍:…...

java_网络服务相关_gateway_nacos_feign区别联系

1. spring-cloud-starter-gateway 作用&#xff1a;作为微服务架构的网关&#xff0c;统一入口&#xff0c;处理所有外部请求。 核心能力&#xff1a; 路由转发&#xff08;基于路径、服务名等&#xff09;过滤器&#xff08;鉴权、限流、日志、Header 处理&#xff09;支持负…...

【HarmonyOS 5.0】DevEco Testing:鸿蒙应用质量保障的终极武器

——全方位测试解决方案与代码实战 一、工具定位与核心能力 DevEco Testing是HarmonyOS官方推出的​​一体化测试平台​​&#xff0c;覆盖应用全生命周期测试需求&#xff0c;主要提供五大核心能力&#xff1a; ​​测试类型​​​​检测目标​​​​关键指标​​功能体验基…...

java调用dll出现unsatisfiedLinkError以及JNA和JNI的区别

UnsatisfiedLinkError 在对接硬件设备中&#xff0c;我们会遇到使用 java 调用 dll文件 的情况&#xff0c;此时大概率出现UnsatisfiedLinkError链接错误&#xff0c;原因可能有如下几种 类名错误包名错误方法名参数错误使用 JNI 协议调用&#xff0c;结果 dll 未实现 JNI 协…...

iPhone密码忘记了办?iPhoneUnlocker,iPhone解锁工具Aiseesoft iPhone Unlocker 高级注册版​分享

平时用 iPhone 的时候&#xff0c;难免会碰到解锁的麻烦事。比如密码忘了、人脸识别 / 指纹识别突然不灵&#xff0c;或者买了二手 iPhone 却被原来的 iCloud 账号锁住&#xff0c;这时候就需要靠谱的解锁工具来帮忙了。Aiseesoft iPhone Unlocker 就是专门解决这些问题的软件&…...

JUC笔记(上)-复习 涉及死锁 volatile synchronized CAS 原子操作

一、上下文切换 即使单核CPU也可以进行多线程执行代码&#xff0c;CPU会给每个线程分配CPU时间片来实现这个机制。时间片非常短&#xff0c;所以CPU会不断地切换线程执行&#xff0c;从而让我们感觉多个线程是同时执行的。时间片一般是十几毫秒(ms)。通过时间片分配算法执行。…...

自然语言处理——循环神经网络

自然语言处理——循环神经网络 循环神经网络应用到基于机器学习的自然语言处理任务序列到类别同步的序列到序列模式异步的序列到序列模式 参数学习和长程依赖问题基于门控的循环神经网络门控循环单元&#xff08;GRU&#xff09;长短期记忆神经网络&#xff08;LSTM&#xff09…...

OPENCV形态学基础之二腐蚀

一.腐蚀的原理 (图1) 数学表达式&#xff1a;dst(x,y) erode(src(x,y)) min(x,y)src(xx,yy) 腐蚀也是图像形态学的基本功能之一&#xff0c;腐蚀跟膨胀属于反向操作&#xff0c;膨胀是把图像图像变大&#xff0c;而腐蚀就是把图像变小。腐蚀后的图像变小变暗淡。 腐蚀…...