linux 互斥量pthread_mutex

news2024/12/24 2:36:36

  

  • 专栏内容:linux下并发编程
  • 个人主页:我的主页
  • 座右铭:天行健,君子以自强不息;地势坤,君子以厚德载物.

目录

前言

概述

原理

初始化

进程和线程使用的不同点

死锁

接口

基本API

属性设置

带等待超时的接口

代码演示

结尾


前言

本专栏主要分享linux下并发编程相关知识,包括多进程,多线程,进程/线程间通信,并发同步控制,以及高并发下性能提升,请大家多多留言。


概述

本文主要介绍并发编程中的互斥量,linux中提供了一系列pthread_mutex打头的接口完成互斥量的功能。它不同于信号量,在并发编程中应用非常广泛。

原理

互斥量,顾名思义,就是相互排斥,也就是说两个并发任务想要达到顺序排列执行目的时,就要用到互斥量。在关键代码包在互斥量的lock/unlock中间,那么这段代码在多个任务并发时也是顺次执行的,但是它们的顺序是竞争的结果,看谁也争抢到互斥量并加锁。

初始化

有两种形式,一种是静态初始化,使用默认的值,如下;

pthead_mutex_t muetx = PTHREAD_MUTEX_INITIALIZER;

一种是调用初始化API, pthread_mutex_init,这就比较灵活,可以对mutex的属性进行设置。

进程和线程使用的不同点

默认是PTHREAD_PROCESS_PRIVATE 在多线程间的使用,也是就进程内部,进程间的使用PTHREAD_PROCESS_SHARED,同时pthread_mutex_t变量也需要在共享内存中,这样状态的变化在多进程中都可以访问到。

死锁

在互斥量使用的过程中我们要避免死锁的发生,如果有多种锁的使用时,还需要增加死锁检测机制,而不仅仅是靠代码保证。

几种防止策略,一是尽量使用单一的互斥量锁;二是互斥量锁间避免嵌套使用;三是嵌套使用时,按一定次序进行加锁,避免无序加锁;四是使用带有超时的加锁方法,在超时时释放持有的其它锁;

接口

基本API

头文件

#include <pthread.h>

/*创建并初始化,以及销毁*/

int pthread_mutex_init(pthread_mutex_t *restrict mutex, const pthread_mutexattr_t *restrict attr);

int pthread_mutex_destroy(pthread_mutex_t *mutex);

/* 加锁,尝试加锁,解锁 */

int pthread_mutex_lock(pthread_mutex_t *mutex);

int pthread_mutex_trylock(pthread_mutex_t *mutex);

int pthread_mutex_unlock(pthread_mutex_t *mutex);

属性设置

头文件

#include <pthread.h>

/* mutex attribute创建初始化,以及销毁  */

int pthread_mutexattr_init(pthread_mutexattr_t *attr);

int pthread_mutexattr_destroy( pthread_mutexattr_t *attr );

(1)共享属性

int pthread_mutexattr_getpshared(const pthread_mutexattr_t *attr,

                                        int *pshared);

int pthread_mutexattr_setpshared(pthread_mutexattr_t *attr,

                                        int pshared);

设置属性取值为:

PTHREAD_PROCESS_PRIVATE,mutex在单进程的线程间共享使用。这是默认取值。

PTHREAD_PROCESS_SHARED,mutex可以在任意线程间使用,只要可以访问到mutex的线程,也就是在多进程间也可以使用。

(2)健壮(robust)属性

int pthread_mutexattr_getrobust(const pthread_mutexattr_t *attr,

                                       int *robustness);

int pthread_mutexattr_setrobust(const pthread_mutexattr_t *attr,

                                       int robustness);

设置属性值为:

PTHREAD_MUTEX_STALLED,当持有lock的线程在中止前没有调用unlock,那么其它等待该mutex的线程将不能获取到,一直会被阻塞。这是默认值。

PTHREAD_MUTEX_ROBUST,当持有lock的线程在中止前没有调用unlock,那么其它等待者可以获得,在下一个获得mutex的线程,得到的返回码为EOWNERDEAD,此时需要调用pthread_mutex_consistent,让mutex的状态进行同步,否则不能进行其它操作。

(3)类型属性

int pthread_mutexattr_gettype(const pthread_mutexattr_t *restrict attr,

           int *restrict type);

int pthread_mutexattr_settype(pthread_mutexattr_t *attr, int type);

类型属性,主要对于重复lock,还有重复unlock的行为,在不同类型下,以及与健壮属性的结合时,有不同的表现,具体解释如下:

PTHREAD_MUTEX_NORMAL ,不会检测重复加锁产生的死锁,对于没加锁时调用unlock或重复unlock由健壮属性决定;

PTHREAD_MUTEX_ERRORCHECK ,检测死锁和没持用锁时的unlock行为,都返回错误码;

PTHREAD_MUTEX_RECURSIVE ,当前线程重复lock时,会成功,mutex只是增加count值,当然unlock的次数也需要对应,只有count为零时才能真正释放锁。在调用pthread_mutex_trylock时,会对count值递增;其它三种类型下,如果被lock时(即使是当前线程lock)会立即返回。

PTHREAD_MUTEX_DEFAULT,默认值,对上述两种行为未定义,如果存在时使用以上三种类型。

以上几种属性组合后的影响如下:

mutext类型

健壮属性

重复加锁

没加锁时unlock或重复unlock

PTHREAD_MUTEX_NORMAL

PTHREAD_MUTEX_STALLED

产生死锁

未定义的行为

PTHREAD_MUTEX_NORMAL

PTHREAD_MUTEX_ROBUST

产生死锁

返回错误

PTHREAD_MUTEX_ERRORCHECK

任意

返回错误

返回错误

PTHREAD_MUTEX_RECURSIVE

任意

递归加锁

返回错误

PTHREAD_MUTEX_DEFAULT

PTHREAD_MUTEX_STALLED

未定义的行为

未定义的行为

PTHREAD_MUTEX_DEFAULT

PTHREAD_MUTEX_ROBUST

未定义的行为

返回错误

                                                                       

带等待超时的接口

#include <pthread.h>

#include <time.h>

int pthread_mutex_timedlock(pthread_mutex_t *restrict mutex, const struct timesec *restrict tsptr);

在尝试加锁时,可以设置tsptr超时时间;这样可以避免死锁的发生。

代码演示

在我的gitcode工程中,链接如下:

韩楚风 / hatchCode · GitCode

以往都会在博客中粘贴代码,发现代码多时,在博客中就看不清代码结构,幸好csdn也开放了gitcode,这样可以看到整个代码,并且可以完整下载运行。

本次的代码路径为hatchCode/ex04_process,实现了多进程间的互斥锁演示,大家也可以在此代码框加上继续开发。

[senllang@localhost ex04_process]$ pwd
/home/senllang/Dev/hatchCode/ex04_process

[senllang@localhost ex04_process]$ ll
total 32
-rw-r--r--. 1 senllang develops 2273 May  3 12:05 ipc_mutex.c
-rw-r--r--. 1 senllang develops  955 May  3 12:05 ipc_mutex.h
-rw-r--r--. 1 senllang develops 1526 May  3 12:05 ipc_shmem.c
-rw-r--r--. 1 senllang develops  719 May  3 12:05 ipc_shmem.h
-rw-r--r--. 1 senllang develops 1506 May  3 12:05 main.c
-rw-r--r--. 1 senllang develops 1497 May  3 12:05 Makefile
-rw-r--r--. 1 senllang develops 1243 May  3 12:05 process.c
-rw-r--r--. 1 senllang develops  690 May  3 12:05 process.h

 


结尾

作者邮箱:study@senllang.onaliyun.com
如有错误或者疏漏欢迎指出,互相学习。另外有什么想要了解的内容,也可以给我发邮件,互相谈讨,定知无不言。

注:未经同意,不得转载!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/500053.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

探索机器翻译:从统计机器翻译到神经机器翻译

❤️觉得内容不错的话&#xff0c;欢迎点赞收藏加关注&#x1f60a;&#x1f60a;&#x1f60a;&#xff0c;后续会继续输入更多优质内容❤️ &#x1f449;有问题欢迎大家加关注私戳或者评论&#xff08;包括但不限于NLP算法相关&#xff0c;linux学习相关&#xff0c;读研读博…

Osek网络管理及ETAS实现

OSEK/VDX&#xff08;Offene Systeme und deren Schnittstellen fr die Elektronik in Kraftfahrzeugen / Vehicle Distributed eXecutive&#xff09;是一种用于嵌入式系统&#xff08;尤其是汽车电子控制单元&#xff09;的开放标准。它旨在提供一种统一、可互操作的软件架构…

关于 《python 从入门到实践》的 matplotlib 随机漫步小项目

使用 python 生成随机漫步数据&#xff0c;再使用 matplotlib 将数据呈现。 所谓随机漫步&#xff1a; 每次行走的路径都是完全随机的&#xff0c;就像蚂蚁在晕头转向的情况下&#xff0c;每次都沿随机方向前行路径。 在自然界&#xff0c;物理学&#xff0c;生物学&#xff0…

【Linux】Job for network.service failed(网卡启动报错)

上图是Linux网卡启动报错的情况 这是由于cat/etc/sysconfig/network-scripts/ifcfg-xxx 中HWADDR的MAC地址和ifconfig中的MAC地址不一样&#xff0c;或者缺少cat/etc/sysconfig/network-scripts/ifcfg-xxx 中HWADDR的MAC地址 1.查看ifconfig中的MAC地址 图中00&#xff1a;0c…

【新星计划-2023】IP地址是什么?IP地址的主要功能是什么?

IP地址在生活中是很常见的&#xff0c;我们所使用的手机、电脑等等&#xff0c;都有一个IP地址&#xff0c;那么IP地址是什么&#xff1f;通过IP地址又能干什么&#xff1f;下文就来给大家详细的讲解一下。 一、什么是IP地址 通常我们说的IP地址多数是指互联网中联网的IP地址…

Java 基础进阶篇(十一)—— Arrays 与 Collections 工具类

文章目录 一、Arrays工具类1.1 Arrays 类常用方法1.2 对于 Comparator 比较器的支持1.3 Arrays 的综合应用1.3.1 应用一&#xff1a;数组的降序排序1.3.2 应用二&#xff1a;根据学生年龄进行排序 二、Collections工具类2.1 Collections 类常用方法2.2 Collections 排序相关 AP…

神经网络实验---梯度下降法

本次实验主要目的是掌握梯度下降法的基本原理&#xff0c;能够使用梯度下降法求解一元和多元线性回归问题。 文章目录 目录 文章目录 1. 实验目的 2. 实验内容 3. 实验过程 题目一&#xff1a; 题目二&#xff1a; 题目三&#xff1a; 实验小结&讨论题 1. 实验目的 ① 掌握…

〖Python网络爬虫实战㉓〗- Ajax数据爬取之什么是Ajax

订阅&#xff1a;新手可以订阅我的其他专栏。免费阶段订阅量1000 python项目实战 Python编程基础教程系列&#xff08;零基础小白搬砖逆袭) 说明&#xff1a;本专栏持续更新中&#xff0c;目前专栏免费订阅&#xff0c;在转为付费专栏前订阅本专栏的&#xff0c;可以免费订阅付…

23.5.7总结(学习通项目思路)

项目思路&#xff1a; 注册&#xff1a;输入邮箱&#xff08;判重&#xff09;&#xff0c;两次输入密码&#xff0c;获得的正确的验证码&#xff0c;获得不重复的用户名。 登录&#xff1a;输入用户名和密码登录。 忘记密码&#xff1a;输入邮箱&#xff08;和用户名&#…

RK3588平台开发系列讲解(进程篇)可执行文件内部结构

平台内核版本安卓版本RK3588Linux 5.10Android 12文章目录 一、 ELF 文件的两大组成部分二、文件头三、程序头和节区头四、ELF 文件的细节结构沉淀、分享、成长,让自己和他人都能有所收获!😄 📢在 Linux 中,二进制可执行文件的标准格式叫做 ELF(Executable and Linkabl…

ARP协议结构

文章目录 概念ARP协议格式ARP协议的作用ARP协议的工作流程 首先提出一个问题&#xff0c;来理解ARP解决什么问题 已知报文在数据链路层传输的过程中&#xff08;假设是主机A到主机B&#xff09;&#xff0c;是通过路由器之间的跳转&#xff0c;根据路由表&#xff0c;结合目的…

【论文】SimCLS:一个简单的框架 摘要总结的对比学习(1)

SimCLS:摘要总结的对比学习(1&#xff09; 写在最前面模型框架 摘要1 简介 写在最前面 SimCLS: A Simple Framework for Contrastive Learning of Abstractive Summarization&#xff08;2021ACL会议&#xff09; https://arxiv.org/abs/2106.01890 论文&#xff1a;https://…

【c语言小demo】登录demo | 账号密码验证功能

创作不易&#xff0c;本篇文章如果帮助到了你&#xff0c;还请点赞 关注支持一下♡>&#x16966;<)!! 主页专栏有更多知识&#xff0c;如有疑问欢迎大家指正讨论&#xff0c;共同进步&#xff01; 给大家跳段街舞感谢支持&#xff01;ጿ ኈ ቼ ዽ ጿ ኈ ቼ ዽ ጿ ኈ ቼ …

postgresql insert ddl执行流程分析

专栏内容&#xff1a;postgresql内核源码分析个人主页&#xff1a;我的主页座右铭&#xff1a;天行健&#xff0c;君子以自强不息&#xff1b;地势坤&#xff0c;君子以厚德载物&#xff0e; 目录 前言 总体流程 调用堆栈 执行接口说明 详细流程分解 ExecInsert对于普通表…

Java9

Java9 &#xff08;一&#xff09;、stream流1.1 Stream流的中间方法和终结方法 &#xff08;二&#xff09;、方法引用2.1 方法引用的分类 &#xff08;三&#xff09;、异常3.1 编译时异常和运行时异常3.2 异常的作用3.3 异常的处理方式3.4 异常中的常见方法3.5 自定义异常 &…

麒麟设置分辨率

为什么要设置------额。。。。虚拟机启动的&#xff0c;直接满屏了。。。。也不能移动 命令设置法 1、可以通过xrandr命令来设置屏幕分辨率。先查询当前分辨率&#xff0c;及当前支持的分辨率。 xrandr 2、可以通过-s参数来设置为1920x1440 xrandr -s 1920x1440 这就好…

Midjouney prompt优化

Midjouney prompt优化 总述1. Midjouney1.1 常见出图方式1.2 图片参数 2. prompt2.1 prompt关键词框架逻辑2.2 关键词技巧2.3 分类关键词2.3.1 媒体类型、介质和渲染引擎2.3.2 艺术风格2.3.2.1常见风格关键词2.3.2.2 艺术风格介绍2.3.2.3 绘画风格关键词和作品 2.3.3 相机镜头和…

面试官从这些方面考察你的Android开发水平!

View基础(25题) 什么是ViewView的位置参数MotionEventViewRootDecorViewMeasureSpec View三大流程(28题) measure过程ViewViewGrouplayout过程draw过程获取View的宽高Activity启动到加载ViewRoot的流程 自定义View(26题) 四种实现方法直接继承View自定义属性直接继承ViewG…

C++三大特性—继承“复杂的菱形继承及菱形虚拟继承”

C的一个大坑&#xff1a;菱形继承 希望这篇文章能让你理解什么是菱形继承&#xff0c;以及菱形继承的注意事项 单继承与多继承 单继承&#xff1a;一个子类只有一个直接父类时称这个继承关系为单继承 多继承&#xff1a;一个子类有两个或以上直接父类时称这个继承关系为多继承…

【半监督学习】Match系列.2

本文简单介绍半监督算法中的Match系列方法&#xff1a;CoMatch&#xff08;ICCV2021&#xff09;&#xff0c;CRMatch&#xff08;GCPR2021&#xff09;&#xff0c;Dash&#xff08;ICML2021&#xff09;&#xff0c;UPS&#xff08;ICLR2021&#xff09;&#xff0c;SimMatch…