【锁的区别】C++线程库和POSIX线程库锁的区别
C++线程库和POSIX线程库锁的区别
- C++线程库
- 代码段的互斥:mutex、recursive_mutex、timed_mutex、recursive_timed_mutex
- 互斥量mutex:直接进行lock()或者unlock()
- 递归互斥锁recursive_mutex:可以多次加锁,意味着加几次锁就需要解几次锁
- 定时互斥锁timed_mutex:可以定时加锁,规定什么时间让临界区代码实现互斥访问
- 递归定时互斥锁recursive_timed_mutex:在规定加锁时间的同时,还能实现递归的多次加锁要求
- lock_guard:RAII的方式封装了锁
- unique_lock:RAII方式+加锁/解锁
- 变量的原子性操作:atomic
- POSIX线程库
- 互斥锁:pthread_mutex
- 自旋锁:pthread_spin
- 读写锁:pthread_rwlock
C++线程库
C++线程库中提供了多种类型的原子性操作,主要分为变量的原子性操作和代码段的互斥加锁
代码段的互斥:mutex、recursive_mutex、timed_mutex、recursive_timed_mutex
如果一段代码是在多线程编程下执行的,那么必然要涉及到线程安全的问题,需要对该代码段进行加锁保护
#include <iostream>
#include <mutex>
#include <thread>
#include <vector>std::mutex g_mutex;
int g_count = 0;void Counter() {g_mutex.lock();int i = ++g_count;std::cout << "count: " << i << std::endl;// 前面代码如有异常,unlock 就调不到了。g_mutex.unlock();
}int main() {const std::size_t SIZE = 4;// 创建一组线程。std::vector<std::thread> v;v.reserve(SIZE);for (std::size_t i = 0; i < SIZE; ++i) {v.emplace_back(&Counter);}// 等待所有线程结束。for (std::thread& t : v) {t.join();}return 0;
}
互斥量mutex:直接进行lock()或者unlock()
上述例子中,使用了mutex这个锁,也就是c++中提出的锁,但是这样的方式导致一个线程执行g_count时,其他线程在进行阻塞等待,是有其自己的缺陷的
递归互斥锁recursive_mutex:可以多次加锁,意味着加几次锁就需要解几次锁
定时互斥锁timed_mutex:可以定时加锁,规定什么时间让临界区代码实现互斥访问
递归定时互斥锁recursive_timed_mutex:在规定加锁时间的同时,还能实现递归的多次加锁要求
lock_guard:RAII的方式封装了锁
使用了RAII的思想,让类对象1去管理锁资源,在创建对象的时候加锁,析构对象的时候解锁,以此来预防死锁
unique_lock:RAII方式+加锁/解锁
除了使用RAII的思想之外,还提供了加锁解锁修改锁的功能,比lock_guard增加了一些对锁的操作
变量的原子性操作:atomic
int a
这个变量在整个多线程编程中如果是一个全局变量(局部变量也可以),那么当多个线程需要对其进行修改操作时,必然涉及到线程安全的问题,需要对这个变量加锁保护,但是使用上述的mutex类型会显得大炮打苍蝇,有点兴师动众了,同时如果使用mutex加锁的方式来实现互斥,会让其他线程处于阻塞等锁的状态,会影响程序的效率
c++11中提供了一系列原子操作
#include <iostream>
using namespace std;
#include <thread>
//需要包含对应的头文件
#include <atomic>
atomic_long sum{ 0 };
void fun(size_t num)
{for (size_t i = 0; i < num; ++i)sum ++; // 原子操作
}
int main()
{cout << "Before joining, sum = " << sum << std::endl;thread t1(fun, 1000000);thread t2(fun, 1000000);t1.join();t2.join();cout << "After joining, sum = " << sum << std::endl;return 0;
}
将普通变量修改为原子类型的变量,这样就无需进行加锁解锁操作了,会使代码的运行效率更高,线程自己就能够对这些原子类型的变量实现互斥访问了
POSIX线程库
互斥锁:pthread_mutex
有线程尝试加互斥锁时,如果没有加到锁,该线程会挂起并且切换,只有当其他线程将该互斥锁释放之后,该线程才会被唤醒继续加锁。
和C++中的mutex相似,可以对临界区代码进行加锁保护,但是需要对该互斥锁初始化,并且需要进行销毁
pthread_mutex_init()//初始化
pthread_mutex_lock()//加锁
pthread_mutex_unlock()//解锁
pthread_mutex_destroy()//销毁
自旋锁:pthread_spin
与互斥锁相比,它的效率更高,但是也更占CPU资源。
当有线程尝试加自旋锁时,如果该线程没有加到锁,那么会持续加锁,直到拿到锁为止,线程不会挂起也不会切换,因此加锁效率高,但也更加占用CPU资源
读写锁:pthread_rwlock
当存在这样的场景时:对数据的修改操作少,有大量的读数据操作,在这样的情况下对临界资源进行加锁会导致程序效率低下,那么就需要有一个读不加锁,而只有在写数据的时候才进行加锁来提高程序的效率,读写锁就是这样一个锁
读共享,写独占,读锁优先级高
相关文章:

【锁的区别】C++线程库和POSIX线程库锁的区别
C线程库和POSIX线程库锁的区别 C线程库代码段的互斥:mutex、recursive_mutex、timed_mutex、recursive_timed_mutex互斥量mutex:直接进行lock()或者unlock()递归互斥锁recursive_mutex:可以多次加锁,意味着加几次锁就需要解几次锁…...

网络层·IP协议
承接前文TCP协议-CSDN博客 简介 协议头格式 网段划分(重要) 划分方法 IP地址的数量限制(背景介绍) 私有IP地址和公网IP地址(提出解决思路) NAT技术(解决方法) 路由 网络层 在复杂的网络环境中确定一个合适的路径 IP协议 主机: 配有IP地址, 可以认为就是你的电脑; 路由器:…...

RabbitMQ学习笔记(下):延迟队列,发布确认高级,备份交换机
十、延迟队列 延迟队列 概念: 延迟队列使用场景: 流程图: 延迟队列整合Springboot 导入依赖: <dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot…...

Python 无废话-基础知识面向对象编程详解
类定义 如何理解万物皆对象? 生活中一些事物,动物(可爱的小狗、调皮的小猫)、交通工具(比亚迪U8汽车、飞机)、人(学生、教师)…… 这些对象都有着独特或共性的属性和方法来描述其…...

凉鞋的 Unity 笔记 106. 第二轮循环场景视图Sprite Renderer
106. 第二轮循环&场景视图&Sprite Renderer 从这一篇开始,我们开始进行第二轮循环。 这次我们至少能够在游戏运行窗口看到一些东西。 首先还是在场景层次窗口进行编辑,先创建一个 Sprite,操作如下: 创建后,会在 Scene …...

Vue中如何进行分布式路由配置与管理
Vue中的分布式路由配置与管理 随着现代Web应用程序的复杂性不断增加,分布式路由配置和管理成为了一个重要的主题。Vue.js作为一种流行的前端框架,提供了多种方法来管理Vue应用程序的路由。本文将深入探讨在Vue中如何进行分布式路由配置与管理࿰…...

Solidity 合约漏洞,价值 38BNB 漏洞分析
Solidity 合约漏洞,价值 38BNB 漏洞分析 1. 漏洞简介 https://twitter.com/NumenAlert/status/1626447469361102850 https://twitter.com/bbbb/status/1626392605264351235 2. 相关地址或交易 攻击交易: https://bscscan.com/tx/0x146586f05a451313…...

【C++】:类和对象(2)
朋友们、伙计们,我们又见面了,本期来给大家解读一下有关Linux的基础知识点,如果看完之后对你有一定的启发,那么请留下你的三连,祝大家心想事成! C 语 言 专 栏:C语言:从入门到精通 数…...
【GIT版本控制】--提交更改
一、添加文件到暂存区 在GIT中,要提交更改,首先需要将文件添加到暂存区(Staging Area)。这是一个用于存放将要提交的更改的临时区域。以下是将文件添加到暂存区的步骤: 打开终端或命令提示符:首先&#x…...

解决高分屏DPI缩放PC端百度网盘界面模糊的问题
第一步 更新最新版本 首先,在百度网盘官网下载最新安装包: https://pan.baidu.com/download 进行覆盖安装 第二步 修改兼容性设置 右键百度网盘图标,点击属性,在兼容性选项卡中点击更改所有用户的设置 弹出的选项卡中选择更改高…...

全能视频工具 VideoProc Converter 4K for mac中文
VideoProc 4K提供快速完备的4K影片处理方案,您可以透过这款软体调节输出影片格式和大小。能够有效压缩HD/4K影片体积90%以上,以便更好更快地上传到YouTube,或是通过电子邮件附件发送。业界领先的视讯压缩引擎,让你轻松处理大体积视…...

Vue中实现自定义编辑邮件发送到指定邮箱(纯前端实现)
formspree里面注册账号 注册完成后进入后台新建项目并且新建表单 这一步完成之后你将得到一个地址 最后就是在项目中请求这个地址 关键代码如下: submitForm() {this.fullscreenLoading true;this.$axios({method: "post",url: "https://xxxxxxx…...

计算机专业毕业设计项目推荐11-博客项目(Go+Vue+Mysql)
博客项目(GoVueMysql) **介绍****系统总体开发情况-功能模块****各部分模块实现** 介绍 本系列(后期可能博主会统一为专栏)博文献给即将毕业的计算机专业同学们,因为博主自身本科和硕士也是科班出生,所以也比较了解计算机专业的毕业设计流程以及模式&am…...
QT实现TCP
#include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this);//实例化一个服务器server new QTcpServer(this);// 此时,服务器已经成功进入监听状态,…...

PostgreSQL ash —— pgsentinel插件
一、 插件作用 众所周知,pg是没有像oracle那样的ash视图的,因此要回溯历史问题不太方便。pgsentinel插件会将pg_stat_activity与pg_stat_statements视图内容定期快照,并存入pg_active_session_history和pg_stat_statements_history视图中。 1…...

【刷题笔记10.5】LeetCode:排序链表
LeetCode:排序链表 一、题目描述 给你链表的头结点 head ,请将其按 升序 排列并返回 排序后的链表 。 二、分析 这题咱们默认要求:空间复杂度为O(1)。所以这把咱们用自底向上的方法实现归并排序,则可以达到O(1) 的空间复杂…...

三、【色彩模式与颜色填充】
文章目录 Photoshop常用的几种颜色模式包括:1. RGB模式2. CMYK模式3. 灰度模式4. LAB模式5. 多通道模式 Photoshop颜色填充1.色彩基础2.拾色器认识3.颜色填充最后附上流程图: Photoshop常用的几种颜色模式包括: 1. RGB模式 详细可参考&…...

karmada v1.7.0安装指导
前言 安装心得 经过多种方式操作,发现二进制方法安装太复杂,证书生成及其手工操作太多了,没有安装成功;helm方式的安装,v1.7.0的chart包执行安装会报错,手工修复了报错并修改了镜像地址,还是各…...

OK3568 forlinx系统编译过程及问题汇总
1. 共享文件夹无法加载;通过网上把文件夹加载后,拷贝文件很慢,任务管理器查看发现硬盘读写速率很低。解决办法:重新安装vmware tools。 2. 拷贝Linux源码到虚拟机,解压。 3. 虚拟机基本库安装 forlinxubuntu:~$ sudo…...
JVM篇---第五篇
系列文章目录 文章目录 系列文章目录一、简述Java的对象结构二、如何判断对象可以被回收?三、JVM的永久代中会发生垃圾回收么?一、简述Java的对象结构 Java对象由三个部分组成:对象头、实例数据、对齐填充。 对象头由两部分组成,第一部分存储对象自身的运行时数据:哈希码…...
工程地质软件市场:发展现状、趋势与策略建议
一、引言 在工程建设领域,准确把握地质条件是确保项目顺利推进和安全运营的关键。工程地质软件作为处理、分析、模拟和展示工程地质数据的重要工具,正发挥着日益重要的作用。它凭借强大的数据处理能力、三维建模功能、空间分析工具和可视化展示手段&…...

ServerTrust 并非唯一
NSURLAuthenticationMethodServerTrust 只是 authenticationMethod 的冰山一角 要理解 NSURLAuthenticationMethodServerTrust, 首先要明白它只是 authenticationMethod 的选项之一, 并非唯一 1 先厘清概念 点说明authenticationMethodURLAuthenticationChallenge.protectionS…...

mysql已经安装,但是通过rpm -q 没有找mysql相关的已安装包
文章目录 现象:mysql已经安装,但是通过rpm -q 没有找mysql相关的已安装包遇到 rpm 命令找不到已经安装的 MySQL 包时,可能是因为以下几个原因:1.MySQL 不是通过 RPM 包安装的2.RPM 数据库损坏3.使用了不同的包名或路径4.使用其他包…...

基于Springboot+Vue的办公管理系统
角色: 管理员、员工 技术: 后端: SpringBoot, Vue2, MySQL, Mybatis-Plus 前端: Vue2, Element-UI, Axios, Echarts, Vue-Router 核心功能: 该办公管理系统是一个综合性的企业内部管理平台,旨在提升企业运营效率和员工管理水…...

【从零开始学习JVM | 第四篇】类加载器和双亲委派机制(高频面试题)
前言: 双亲委派机制对于面试这块来说非常重要,在实际开发中也是经常遇见需要打破双亲委派的需求,今天我们一起来探索一下什么是双亲委派机制,在此之前我们先介绍一下类的加载器。 目录 编辑 前言: 类加载器 1. …...
【前端异常】JavaScript错误处理:分析 Uncaught (in promise) error
在前端开发中,JavaScript 异常是不可避免的。随着现代前端应用越来越多地使用异步操作(如 Promise、async/await 等),开发者常常会遇到 Uncaught (in promise) error 错误。这个错误是由于未正确处理 Promise 的拒绝(r…...
Python网页自动化Selenium中文文档
1. 安装 1.1. 安装 Selenium Python bindings 提供了一个简单的API,让你使用Selenium WebDriver来编写功能/校验测试。 通过Selenium Python的API,你可以非常直观的使用Selenium WebDriver的所有功能。 Selenium Python bindings 使用非常简洁方便的A…...

算术操作符与类型转换:从基础到精通
目录 前言:从基础到实践——探索运算符与类型转换的奥秘 算术操作符超级详解 算术操作符:、-、*、/、% 赋值操作符:和复合赋值 单⽬操作符:、--、、- 前言:从基础到实践——探索运算符与类型转换的奥秘 在先前的文…...
DAY 26 函数专题1
函数定义与参数知识点回顾:1. 函数的定义2. 变量作用域:局部变量和全局变量3. 函数的参数类型:位置参数、默认参数、不定参数4. 传递参数的手段:关键词参数5 题目1:计算圆的面积 任务: 编写一…...
书籍“之“字形打印矩阵(8)0609
题目 给定一个矩阵matrix,按照"之"字形的方式打印这个矩阵,例如: 1 2 3 4 5 6 7 8 9 10 11 12 ”之“字形打印的结果为:1,…...