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

C++学习笔记(20)

六、线程安全
示例:
#include <iostream>
#include <thread> // 线程类头文件。
using namespace std;
int aa = 0; // 定义全局变量。
// 普通函数,把全局变量 aa 加 1000000 次。
void func() {
for (int ii = 1; ii <= 1000000; ii++)
aa++;
}
int main()
{
// 用普通函数创建线程。
thread t1(func); // 创建线程 t1,把全局变量 aa 加 1000000 次。
thread t2(func); // 创建线程 t2,把全局变量 aa 加 1000000 次。
t1.join(); // 回收线程 t1 的资源。
t2.join(); // 回收线程 t2 的资源。
cout << "aa=" << aa << endl; // 显示全局变量 aa 的值。
}
242、互斥锁
C++11 提供了四种互斥锁:
 mutex:互斥锁。
 timed_mutex:带超时机制的互斥锁。
 recursive_mutex:递归互斥锁。
 recursive_timed_mutex:带超时机制的递归互斥锁。
包含头文件:#include <mutex> 一、mutex 类
1)加锁 lock()
互斥锁有锁定和未锁定两种状态。
如果互斥锁是未锁定状态,调用 lock()成员函数的线程会得到互斥锁的所有权,并将其上锁。
如果互斥锁是锁定状态,调用 lock()成员函数的线程就会阻塞等待,直到互斥锁变成未锁定状态。
2)解锁 unlock()
只有持有锁的线程才能解锁。
3)尝试加锁 try_lock()
如果互斥锁是未锁定状态,则加锁成功,函数返回 true。
如果互斥锁是锁定状态,则加锁失败,函数立即返回 false。(线程不会阻塞等待)
示例:
#include <iostream>
#include <thread> // 线程类头文件。
#include <mutex> // 互斥锁类的头文件。
using namespace std;
mutex mtx; // 创建互斥锁,保护共享资源 cout 对象。
// 普通函数。
void func(int bh, const string& str) {
for (int ii = 1; ii <= 10; ii++)
{
mtx.lock(); // 申请加锁。
cout << "第" << ii << "次表白:亲爱的" << bh << "号," << str << endl;
mtx.unlock(); // 解锁。
this_thread::sleep_for(chrono::seconds(1)); // 休眠 1 秒。
}
}
int main()
{
// 用普通函数创建线程。
thread t1(func, 1, "我是一只傻傻鸟。");
thread t2(func, 2, "我是一只傻傻鸟。");
thread t3(func, 3, "我是一只傻傻鸟。");
thread t4(func, 4, "我是一只傻傻鸟。");
thread t5(func, 5, "我是一只傻傻鸟。");
t1.join(); // 回收线程 t1 的资源。
t2.join(); // 回收线程 t2 的资源。
t3.join(); // 回收线程 t3 的资源。
t4.join(); // 回收线程 t4 的资源。
t5.join(); // 回收线程 t5 的资源。
}
二、timed_mutex 类
增加了两个成员函数:
bool try_lock_for(时间长度);
bool try_lock_until(时间点);
三、recursive_mutex 类
递归互斥锁允许同一线程多次获得互斥锁,可以解决同一线程多次加锁造成的死锁问题。
示例:
#include <iostream>
#include <mutex> // 互斥锁类的头文件。
using namespace std;
class AA
{
recursive_mutex m_mutex;
public:
void func1() {
m_mutex.lock();
cout << "调用了 func1()\n";
m_mutex.unlock();
}
void func2() {
m_mutex.lock();
cout << "调用了 func2()\n";
func1();
m_mutex.unlock();
}
};
int main()
{
AA aa;
//aa.func1();
aa.func2();
}
四、lock_guard 类
lock_guard 是模板类,可以简化互斥锁的使用,也更安全。
lock_guard 的定义如下:
template<class Mutex>
class lock_guard
{
explicit lock_guard(Mutex& mtx);
}
lock_guard 在构造函数中加锁,在析构函数中解锁。
lock_guard 采用了 RAII 思想(在类构造函数中分配资源,在析构函数中释放资源,保证资源在离开
作用域时自动释放)。
 

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • Unity for Android使用蓝牙低功耗Bluetooth LE
  • linux 操作系统下crontab命令及使用案例介绍
  • mysql对于上期同期的时间的处理
  • 【QT】使用QOpenGLWidget后,窗口全屏之后右键菜单出不来的问题
  • 软件测试面试少走弯路
  • burp suite professional 产品介绍
  • 程序员转行方向推荐
  • 99AutoML 自动化机器学习实践--NNI 自动化机器学习工具包
  • Rider使用习惯
  • 【C++】——string类的模拟实现
  • OpenAI o1 Review 大模型PHD水平数理推理能力 OpenAI o1 vs GPT4o vs Gemini vs Claude
  • SVN的使用技巧
  • 《黑神话:悟空》怎么备份游戏存档?
  • 【C++】认识C++(前言)
  • 顶级高效的ChatGPT论文润色提示词和使用技巧
  • “大数据应用场景”之隔壁老王(连载四)
  • Electron入门介绍
  • ES6核心特性
  • JSONP原理
  • mysql innodb 索引使用指南
  • Promise面试题2实现异步串行执行
  • Redis 懒删除(lazy free)简史
  • TypeScript实现数据结构(一)栈,队列,链表
  • webgl (原生)基础入门指南【一】
  • 构建二叉树进行数值数组的去重及优化
  • 基于OpenResty的Lua Web框架lor0.0.2预览版发布
  • 基于Volley网络库实现加载多种网络图片(包括GIF动态图片、圆形图片、普通图片)...
  • 将 Measurements 和 Units 应用到物理学
  • 聊聊hikari连接池的leakDetectionThreshold
  • 前端
  • 入门到放弃node系列之Hello Word篇
  • 使用 Xcode 的 Target 区分开发和生产环境
  • 用quicker-worker.js轻松跑一个大数据遍历
  • Play Store发现SimBad恶意软件,1.5亿Android用户成受害者 ...
  • ​ 全球云科技基础设施:亚马逊云科技的海外服务器网络如何演进
  • # Maven错误Error executing Maven
  • # Swust 12th acm 邀请赛# [ A ] A+B problem [题解]
  • (12)目标检测_SSD基于pytorch搭建代码
  • (2024最新)CentOS 7上在线安装MySQL 5.7|喂饭级教程
  • (M)unity2D敌人的创建、人物属性设置,遇敌掉血
  • (备份) esp32 GPIO
  • (附源码)ssm经济信息门户网站 毕业设计 141634
  • (附源码)计算机毕业设计ssm本地美食推荐平台
  • (四)JPA - JQPL 实现增删改查
  • (一) storm的集群安装与配置
  • (原創) 博客園正式支援VHDL語法著色功能 (SOC) (VHDL)
  • (转)母版页和相对路径
  • *_zh_CN.properties 国际化资源文件 struts 防乱码等
  • .NET CLR基本术语
  • .Net OpenCVSharp生成灰度图和二值图
  • .net 使用ajax控件后如何调用前端脚本
  • .net 验证控件和javaScript的冲突问题
  • .NET 中小心嵌套等待的 Task,它可能会耗尽你线程池的现有资源,出现类似死锁的情况
  • .NET/C# 使用 #if 和 Conditional 特性来按条件编译代码的不同原理和适用场景
  • .NET6 开发一个检查某些状态持续多长时间的类