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

Linux互斥量读写锁

一、互斥量

1.临界资源

        同一时刻只允许一个进程/线程访问的共享资源(比如文件、外设打印机)

2.临界区

        访问临界资源的代码

3.互斥机制

        mutex互斥锁,用来避免临界资源的访问冲突,访问临界资源前申请互斥锁,访问完释放锁

 形象点的说法 好比有一个公共卫生间,进去使用的人会给门上锁,使用完会开锁

4.创建互斥锁 

/*动态创建*/
pthread_mutex_t mutex
pthread_mutex_t_init(pthread_mutex_t *mutex,互斥锁属性 给NULL默认即可)
/*静态创建*/
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER

5.销毁互斥锁

pthread_mutex_destory(pthread_mutex_t *mutex)

Linux中,互斥锁不占任何资源,所以销毁锁不是必须的,可利用其返回值查询锁状态,锁定时返回EBUSY

6.申请互斥锁(P操作) 

pthread_mutex_lock(pthread_mutex_t *mutex) //无锁时阻塞等待
pthread_mutex_trylock(pthread_mutex_t *mutex) //无锁返回EBUSY

7.释放互斥锁(V操作)

pthread_mutex_unlock(pthread_mutex_t *mutex) 
#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;FILE *fp;
void *func2(void *arg){pthread_detach(pthread_self());printf("This func2 thread\n");char str[]="I write func2 line\n";char c;int i=0;while(1){pthread_mutex_lock(&mutex);while(i<strlen(str)){c = str[i];fputc(c,fp);usleep(1);i++;}pthread_mutex_unlock(&mutex);i=0;usleep(1);}pthread_exit("func2 exit");}void *func(void *arg){pthread_detach(pthread_self());printf("This is func1 thread\n");char str[]="You read func1 thread\n";char c;int i=0;while(1){pthread_mutex_lock(&mutex);while(i<strlen(str)){c = str[i];fputc(c,fp);i++;usleep(1);}pthread_mutex_unlock(&mutex);i=0;usleep(1);}pthread_exit("func1 exit");
}int main(){pthread_t tid,tid2;void *retv;int i;fp = fopen("1.txt","a+");if(fp==NULL){perror("fopen");return 0;}pthread_create(&tid,NULL,func,NULL);pthread_create(&tid2,NULL,func2,NULL);while(1){    sleep(1);} }

二、读写锁

与互斥锁的区别是:

  • 互斥锁对所有线程一视同仁,同一时刻只允许一个线程访问临界资源

  • 读写锁区分读者和写者同一时刻只允许一个写者访问临界资源,而读者允许多个同时访问,更具体地:

    • 写锁状态时,其他写锁、读锁都被阻塞;

    • 读锁状态时,读锁不阻塞,写锁阻塞,但在写锁阻塞之后申请的读锁要阻塞等待写锁(否则重要的内容一直写不进去)

pthread_rwlock_t rwlock //定义读写锁
/*申请写锁*/
pthread_rwlock_wrlock(pthread_rwlock_t *rwlock)
pthread_rwlock_trywrlock(pthread_rwlock_t *rwlock)
/*申请读锁*/
pthread_rwlock_rdlock(pthread_rwlock_t *rwlock)
pthread_rwlock_tryrdlock(pthread_rwlock_t *rwlock)
/*释放锁*/
pthread_rwlock_unlock(pthread_rwlock_t *rwlock)
/*销毁读写锁*/
pthread_rwlock_destory(pthread_rwlock_t *rwlock)
#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>pthread_rwlock_t rwlock;FILE *fp;
void * read_func(void *arg){pthread_detach(pthread_self());printf("read thread\n");char buf[32]={0};while(1){//rewind(fp);pthread_rwlock_rdlock(&rwlock);while(fgets(buf,32,fp)!=NULL){printf("%d,rd=%s\n",(int)arg,buf);usleep(1000);}pthread_rwlock_unlock(&rwlock);sleep(1);}}void *func2(void *arg){pthread_detach(pthread_self());printf("This func2 thread\n");char str[]="I write func2 line\n";char c;int i=0;while(1){pthread_rwlock_wrlock(&rwlock);while(i<strlen(str)){c = str[i];fputc(c,fp);usleep(1);i++;}pthread_rwlock_unlock(&rwlock);i=0;usleep(1);}pthread_exit("func2 exit");}void *func(void *arg){pthread_detach(pthread_self());printf("This is func1 thread\n");char str[]="You read func1 thread\n";char c;int i=0;while(1){pthread_rwlock_wrlock(&rwlock);while(i<strlen(str)){c = str[i];fputc(c,fp);i++;usleep(1);}pthread_rwlock_unlock(&rwlock);i=0;usleep(1);}pthread_exit("func1 exit");
}int main(){pthread_t tid1,tid2,tid3,tid4;void *retv;int i;fp = fopen("1.txt","a+");if(fp==NULL){perror("fopen");return 0;}pthread_rwlock_init(&rwlock,NULL);pthread_create(&tid1,NULL,read_func,1);pthread_create(&tid2,NULL,read_func,2);pthread_create(&tid3,NULL,func,NULL);pthread_create(&tid4,NULL,func2,NULL);while(1){    sleep(1);} }

死锁的避免

概念:有两把锁以上时,多个线程各自申请到锁时,紧接着申请其他线程占用着的锁,它们都会处于阻塞等待,形成【死锁】

避免方法:

  • 锁越少越好,一把锁无需考虑死锁问题

  • 调整锁的顺序

    • 一种笨策略是,某个线程如果想要申请多个锁,那么可以等其释放完,其他线程再申请

    • 另一种笨策略是,各个线程按同样的顺序申请多个锁

 

相关文章:

Linux互斥量读写锁

一、互斥量 1.临界资源 同一时刻只允许一个进程/线程访问的共享资源&#xff08;比如文件、外设打印机&#xff09; 2.临界区 访问临界资源的代码 3.互斥机制 mutex互斥锁&#xff0c;用来避免临界资源的访问冲突&#xff0c;访问临界资源前申请互斥锁&#xff0c;访问完释放…...

网络安全之IP伪造

眼下非常多站点的涉及存在一些安全漏洞&#xff0c;黑客easy使用ip伪造、session劫持、xss攻击、session注入等手段危害站点安全。在纪录片《互联网之子》&#xff08;建议搞IT的都要看下&#xff09;中。亚伦斯沃茨&#xff08;真实人物&#xff0c;神一般的存在&#xff09;涉…...

ARM CCA机密计算安全模型之硬件强制安全

安全之安全(security)博客目录导读 [要求 R0004] Arm 强烈建议所有 CCA 实现都使用硬件强制的安全(CCA HES)。本文件其余部分假设系统启用了 CCA HES。 CCA HES 是一个可信子系统的租户——一个 CCA HES 主机(Host),见下图所示。它将以下监控安全域服务从应用处理元件(P…...

【论文笔记】A Token-level Contrastive Framework for Sign Language Translation

&#x1f34e;个人主页&#xff1a;小嗷犬的个人主页 &#x1f34a;个人网站&#xff1a;小嗷犬的技术小站 &#x1f96d;个人信条&#xff1a;为天地立心&#xff0c;为生民立命&#xff0c;为往圣继绝学&#xff0c;为万世开太平。 基本信息 标题: A Token-level Contrastiv…...

C#窗体简单登录

创建一个Windows登录程序&#xff0c;创建两个窗体&#xff0c;一个用来登录&#xff0c;一个为欢迎窗体&#xff0c;要求输入用户名和密码&#xff08;以个人的姓名和学号分别作为用户名和密码&#xff09;&#xff0c;点击【登录】按钮登录&#xff0c;登录成功后显示欢迎窗体…...

基于ZYNQ-7000系列的FPGA学习笔记3——开发环境搭建点亮一个LED

基于ZYNQ-7000系列的FPGA学习笔记3——开发环境搭建&点亮一个LED 1. 搭建开发环境2. FPGA的开发流程3. 点亮一个LED3.1 实验要求3.2 新建工程3.3 原理图3.4 绘制系统框图3.5 绘制波形图3.6 编写RTL代码3.7 软件仿真3.8 Vivado软件创建工程3.9 分析与综合3.10 设计实现 在上…...

队列-链式描述(C++)

定义 使用链表描述队列时&#xff0c;通常包含以下几个基本要素&#xff1a; 队头指针&#xff08;Front Pointer&#xff09;&#xff1a;指向队列中第一个&#xff08;即最早进入队列的&#xff09;元素的节点。队尾指针&#xff08;Rear Pointer&#xff09;&#xff1a;指…...

Kali Linux使用Netdiscover工具的详细教程

Kali Linux使用Netdiscover工具的详细教程 引言 在网络安全和渗透测试的过程中&#xff0c;网络发现是一个至关重要的步骤。Netdiscover是Kali Linux中一个非常实用的网络发现工具&#xff0c;它可以帮助用户快速识别局域网中的活动设备。本文将详细介绍如何使用Netdiscover工…...

arkTS:使用ArkUI实现用户信息的持久化管理与自动填充(PersistentStorage)

arkUI&#xff1a;使用ArkUI实现用户信息的持久化管理与自动填充&#xff08;PersistentStorage&#xff09; 1 主要内容说明2 例子2.1 登录页2.1.1登陆页的相关说明2.1.1.1 持久化存储的初始化2.1.1.2 输入框2.1.1.3 记住密码选项2.1.1.4 登录按钮的逻辑2.1.1.5 注册跳转 2.1.…...

IntelliJ+SpringBoot项目实战(二十)--基于SpringSecurity实现Oauth2服务端和客户端

在前面的帖子中介绍了SpringSecurityJWT实现了认证和授权的功能。因为基于Oauth2的统一认证在项目需求中越来越多&#xff0c;所以有必要将OAuth2的解决方案也整合进来&#xff0c;这样我们的产品既可以作为一个业务系统&#xff0c;也可以作为一个独立的统一认证服务器。下面详…...

如何实现剪裁功能

文章目录 1 概念介绍2 使用方法2.1 ClipOval2.2 ClipRRect3 示例代码我们在上一章回中介绍了AspectRatio Widget相关的内容,本章回中将介绍剪裁类组件(Clip).闲话休提,让我们一起Talk Flutter吧。 1 概念介绍 我们在这里说的剪裁类组件主要是指对子组件进行剪裁操作,常用的…...

LeetCode 动态规划 爬楼梯

爬楼梯 假设你正在爬楼梯。需要 n 阶你才能到达楼顶。 每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢&#xff1f; 示例 1&#xff1a; 输入&#xff1a;n 2 输出&#xff1a;2 解释&#xff1a;有两种方法可以爬到楼顶。 1 阶 1 阶 2 阶 示例 2&#xff…...

Java 工厂模式:深度解析与应用指南

在 Java 编程的广袤天地里&#xff0c;设计模式宛如璀璨星辰&#xff0c;照亮了开发者构建高效、灵活且可维护软件系统的道路。其中&#xff0c;工厂模式作为创建型设计模式的关键成员&#xff0c;在对象创建环节扮演着举足轻重的角色&#xff0c;极大地增强了代码的适应性与扩…...

HTML5系列(5)-- SVG 集成详解

前端技术探索系列&#xff1a;HTML5 SVG 集成详解 &#x1f3a8; 开篇寄语 &#x1f44b; 前端开发者们&#xff0c; 在前五篇文章中&#xff0c;我们探讨了 HTML5 的多个特性。今天&#xff0c;让我们深入了解 SVG 的魅力&#xff0c;看看如何创建可缩放的矢量图形。 一、…...

深度学习常见数据集处理方法

1、数据集格式转换&#xff08;json转txt&#xff09; import json import os 任务&#xff1a;实例分割&#xff0c;labelme的json文件, 转txt文件 Ultralytics YOLO format <class-index> <x1> <y1> <x2> <y2> ... <xn> <yn> # 类…...

1180 - 【入门】数字出现次数

题目描述 有50个数&#xff08;0-19&#xff09;&#xff0c;求这50个数中相同数字出现的最多次数为几次&#xff1f; 输入 50个数字 输出 1个数字&#xff08;即相同数字出现的最多次数&#xff09; 样例 输入 复制 1 10 2 0 15 8 12 7 0 3 15 0 15 18 16 7 17 16 9 …...

C++20: 像Python一样split字符串

概要 Python 的字符串天生支持 split( ) 操作&#xff0c;支持单个字符或字符串作为分隔符。 C 在这方面显得很笨拙&#xff0c;但是在 C20 下经过一番尝试&#xff0c;还是能够提供类似的简洁调用。 Python 代码 s 0,11,336,23,370nums s.split(,) for n in nums:print(n…...

Unity3D UI 嵌套滚动视图

Unity3D 解决 UI 嵌套滚动视图滑动问题。 嵌套滚动视图 滑动问题 在游戏开发中&#xff0c;我们常常会遇到一种情况&#xff0c;在一个滚动视图列表中&#xff0c;每个 item 还包含了一个内嵌的滚动视图。 这样&#xff0c;当我们在滑动外层的滚动视图时&#xff0c;如果点…...

你还没有将 Siri 接入GPT对话功能吗?

由于各种原因&#xff0c;国内ios用户目前无缘自带 AI 功能&#xff0c;但是这并不代表国内 ios 无法接入 AI 功能&#xff0c;接下来手把手带你为iPhone siri 接入 gpt 对话功能。 siri 接入 chatGPT 暂时还无法下载 ChatGPT app&#xff0c;或者没有账号的读者可以直接跳到…...

_C#_串口助手_字符串拼接缺失问题(未知原理)

最近使用WPF开发串口助手时&#xff0c;遇到一个很奇怪的问题&#xff0c;无论是主线程、异步还是多线程&#xff0c;当串口接收速度达到0.016s一次以上&#xff0c;就会发生字符串缺失问题并且很卡。而0.016s就一切如常&#xff0c;仿佛0.015s与0.016s是天堑之隔。 同一份代码…...

golang循环变量捕获问题​​

在 Go 语言中&#xff0c;当在循环中启动协程&#xff08;goroutine&#xff09;时&#xff0c;如果在协程闭包中直接引用循环变量&#xff0c;可能会遇到一个常见的陷阱 - ​​循环变量捕获问题​​。让我详细解释一下&#xff1a; 问题背景 看这个代码片段&#xff1a; fo…...

Cesium1.95中高性能加载1500个点

一、基本方式&#xff1a; 图标使用.png比.svg性能要好 <template><div id"cesiumContainer"></div><div class"toolbar"><button id"resetButton">重新生成点</button><span id"countDisplay&qu…...

Day131 | 灵神 | 回溯算法 | 子集型 子集

Day131 | 灵神 | 回溯算法 | 子集型 子集 78.子集 78. 子集 - 力扣&#xff08;LeetCode&#xff09; 思路&#xff1a; 笔者写过很多次这道题了&#xff0c;不想写题解了&#xff0c;大家看灵神讲解吧 回溯算法套路①子集型回溯【基础算法精讲 14】_哔哩哔哩_bilibili 完…...

ssc377d修改flash分区大小

1、flash的分区默认分配16M、 / # df -h Filesystem Size Used Available Use% Mounted on /dev/root 1.9M 1.9M 0 100% / /dev/mtdblock4 3.0M...

在Ubuntu中设置开机自动运行(sudo)指令的指南

在Ubuntu系统中&#xff0c;有时需要在系统启动时自动执行某些命令&#xff0c;特别是需要 sudo权限的指令。为了实现这一功能&#xff0c;可以使用多种方法&#xff0c;包括编写Systemd服务、配置 rc.local文件或使用 cron任务计划。本文将详细介绍这些方法&#xff0c;并提供…...

Java求职者面试指南:Spring、Spring Boot、MyBatis框架与计算机基础问题解析

Java求职者面试指南&#xff1a;Spring、Spring Boot、MyBatis框架与计算机基础问题解析 一、第一轮提问&#xff08;基础概念问题&#xff09; 1. 请解释Spring框架的核心容器是什么&#xff1f;它在Spring中起到什么作用&#xff1f; Spring框架的核心容器是IoC容器&#…...

return this;返回的是谁

一个审批系统的示例来演示责任链模式的实现。假设公司需要处理不同金额的采购申请&#xff0c;不同级别的经理有不同的审批权限&#xff1a; // 抽象处理者&#xff1a;审批者 abstract class Approver {protected Approver successor; // 下一个处理者// 设置下一个处理者pub…...

免费数学几何作图web平台

光锐软件免费数学工具&#xff0c;maths,数学制图&#xff0c;数学作图&#xff0c;几何作图&#xff0c;几何&#xff0c;AR开发,AR教育,增强现实,软件公司,XR,MR,VR,虚拟仿真,虚拟现实,混合现实,教育科技产品,职业模拟培训,高保真VR场景,结构互动课件,元宇宙http://xaglare.c…...

Git常用命令完全指南:从入门到精通

Git常用命令完全指南&#xff1a;从入门到精通 一、基础配置命令 1. 用户信息配置 # 设置全局用户名 git config --global user.name "你的名字"# 设置全局邮箱 git config --global user.email "你的邮箱example.com"# 查看所有配置 git config --list…...

根目录0xa0属性对应的Ntfs!_SCB中的FileObject是什么时候被建立的----NTFS源代码分析--重要

根目录0xa0属性对应的Ntfs!_SCB中的FileObject是什么时候被建立的 第一部分&#xff1a; 0: kd> g Breakpoint 9 hit Ntfs!ReadIndexBuffer: f7173886 55 push ebp 0: kd> kc # 00 Ntfs!ReadIndexBuffer 01 Ntfs!FindFirstIndexEntry 02 Ntfs!NtfsUpda…...