Linux下的多线程编程:原理、工具及应用(5)

 

                                               🎬慕斯主页修仙—别有洞天

                                              ♈️今日夜电波:Flower of Life—陽花

                                                                0:34━━━━━━️💟──────── 4:46
                                                                    🔄   ◀️   ⏸   ▶️    ☰  

                                      💗关注👍点赞🙌收藏您的每一次鼓励都是对我莫大的支持😍


 

目录

自旋锁

什么是自旋锁?

pthread_spinlock_t

pthread_spin_init

pthread_spin_lock

pthread_spin_unlock

pthread_spin_trylock

pthread_spin_destroy

读写锁

pthread_rwlock_t

pthread_rwlock_init

pthread_rwlock_destroy

pthread_rwlock_rdlock

pthread_rwlock_wrlock

pthread_rwlock_unlock

pthread_rwlock_tryrdlock

pthread_rwlock_trywrlock


自旋锁

什么是自旋锁?

        自旋锁是一种同步机制,它用于控制多线程环境中对共享资源的访问。

        自旋锁的核心思想是,当一个线程试图获取已经被其他线程持有的锁时,而不是进入阻塞状态,它会在一个循环中不断地检查锁是否可用。一旦锁被释放,这个线程就可以立即获取锁并继续执行。这种机制避免了线程切换的开销,因此在某些情况下可以提高性能。以下是对自旋锁的详细解释:

  1. 不阻塞线程:自旋锁不会使线程进入睡眠状态,而是在用户态进行忙等待。
  2. 适用场景:自旋锁适用于锁持有时间较短的场景,这样等待的线程可以在不久的将来获得锁,而不会浪费太多时间在线程切换上。
  3. 避免上下文切换:由于线程在等待锁时不会进入内核态,因此避免了操作系统进程调度和线程切换的消耗。
  4. 适用性:自旋锁通常用在操作系统内核或其他需要快速响应的场景中,因为它们可以在没有其他线程持有锁的情况下迅速获取锁。
  5. 死锁风险:自旋锁可能会导致死锁,如果多个线程都在无限期地等待同一个资源,这可能导致系统无法正常工作。
  6. 性能考量:自旋锁的性能优势在于减少了线程切换的开销,但如果锁持有时间过长,自旋锁可能会导致CPU资源的浪费。
  7. 实现方式:自旋锁可以通过原子操作来实现,确保在多线程环境下对锁的安全访问。
  8. 与互斥锁的区别:与互斥锁相比,自旋锁在获取锁失败时不会让线程进入睡眠状态,而是保持忙碌等待,这可以减少线程切换的开销,但在锁竞争激烈时可能会增加CPU使用率。

        自旋锁是一种高效的同步机制,适用于锁持有时间短且希望减少线程切换开销的场景。然而,它也有自己的局限性,如可能增加CPU使用率和潜在的死锁风险,因此在使用时需要根据具体情况谨慎选择。

pthread_spinlock_t

pthread_spinlock_t 是一个用于表示自旋锁的数据类型。它通常用于多线程编程中,用于保护共享资源的访问。

在多线程环境中,多个线程可能会同时访问同一个共享资源,这可能导致数据竞争和不一致的结果。为了避免这种情况,可以使用自旋锁来确保在同一时刻只有一个线程能够访问共享资源。

pthread_spinlock_t 是一个无符号整型变量,用于存储自旋锁的状态。它通常与 pthread_spin_init()、pthread_spin_destroy()、pthread_spin_lock() 和 pthread_spin_unlock() 等函数一起使用。

pthread_spin_init

pthread_spin_init 是一个用于初始化自旋锁的函数。它的作用是为一个自旋锁分配内存并初始化其属性。

函数原型:

int pthread_spin_init(pthread_spinlock_t *lock, int pshared);

参数说明:

  • lock:指向要初始化的自旋锁变量的指针。
  • pshared:指定自旋锁的共享属性。如果设置为 PTHREAD_PROCESS_PRIVATE,则该自旋锁只能在同一个进程中的线程之间共享;如果设置为 PTHREAD_PROCESS_SHARED,则该自旋锁可以在不同的进程中的线程之间共享。

返回值:

  • 成功时,返回0;
  • 失败时,返回一个非零的错误码。

pthread_spin_lock

pthread_spin_lock() 是一个用于获取自旋锁的函数。它的作用是尝试获取一个自旋锁,如果锁已经被其他线程持有,则当前线程会进入忙等待状态,不断循环检查锁是否可用,直到获取到锁为止。

函数原型:

int pthread_spin_lock(pthread_spinlock_t *lock);

参数说明:

  • lock:指向要获取的自旋锁变量的指针。

返回值:

  • 成功时,返回0;
  • 失败时,返回一个非零的错误码。

pthread_spin_unlock

pthread_spin_unlock() 是一个用于释放自旋锁的函数。它的作用是释放一个已经获取到的自旋锁,使得其他等待该锁的线程可以继续执行。

函数原型:

int pthread_spin_unlock(pthread_spinlock_t *lock);

参数说明:

  • lock:指向要释放的自旋锁变量的指针。

返回值:

  • 成功时,返回0;
  • 失败时,返回一个非零的错误码。

pthread_spin_trylock

pthread_spin_trylock() 是一个用于尝试获取自旋锁的函数。它的作用是尝试获取一个自旋锁,如果锁已经被其他线程持有,则立即返回失败,不会进入忙等待状态。

函数原型:

int pthread_spin_trylock(pthread_spinlock_t *lock);

参数说明:

  • lock:指向要尝试获取的自旋锁变量的指针。

返回值:

  • 成功时,返回0;
  • 失败时,返回一个非零的错误码。

pthread_spin_destroy

pthread_spin_destroy() 是一个用于销毁自旋锁的函数。它的作用是释放一个已经初始化的自旋锁,以便系统可以回收其占用的资源。

函数原型:

int pthread_spin_destroy(pthread_spinlock_t *lock);

参数说明:

  • lock:指向要销毁的自旋锁变量的指针。

返回值:

  • 成功时,返回0;
  • 失败时,返回一个非零的错误码。

读写锁

pthread_rwlock_t

        pthread_rwlock_t 是一个用于实现读写锁的数据类型,它是POSIX线程库中的一部分。读写锁允许多个线程同时读取共享资源,但在写入时只允许一个线程进行操作。

        读写锁有两种状态:读锁定和写锁定。当一个线程获取读锁定时,其他线程可以继续获取读锁定或等待获取写锁定。当一个线程获取写锁定时,其他线程不能获取读锁定或写锁定,直到写锁定被释放。

        使用 pthread_rwlock_t 需要先初始化读写锁,然后可以使用 pthread_rwlock_init() 函数进行初始化。在不再需要读写锁时,应使用 pthread_rwlock_destroy() 函数销毁它。

        以下是一些常用的读写锁操作函数:

  1. pthread_rwlock_init():初始化读写锁。
  2. pthread_rwlock_destroy():销毁读写锁。
  3. pthread_rwlock_rdlock():获取读锁定。
  4. pthread_rwlock_tryrdlock():尝试获取读锁定,如果无法获取则立即返回。
  5. pthread_rwlock_timedrdlock():在指定时间内尝试获取读锁定,如果无法获取则返回。
  6. pthread_rwlock_wrlock():获取写锁定。
  7. pthread_rwlock_trywrlock():尝试获取写锁定,如果无法获取则立即返回。
  8. pthread_rwlock_timedwrlock():在指定时间内尝试获取写锁定,如果无法获取则返回。
  9. pthread_rwlock_unlock():释放锁定。

pthread_rwlock_init

pthread_rwlock_init() 是一个用于初始化读写锁的函数。它的作用是为一个已经声明的读写锁变量分配内存并初始化其属性。

函数原型:

int pthread_rwlock_init(pthread_rwlock_t *restrict rwlock, const pthread_rwlockattr_t *restrict attr);

参数说明:

  • rwlock:指向要初始化的读写锁变量的指针。
  • attr:指向读写锁属性对象的指针,如果传入NULL,则使用默认属性。

返回值:

  • 成功时,返回0;
  • 失败时,返回一个非零的错误码。

pthread_rwlock_destroy

pthread_rwlock_destroy() 是一个用于销毁读写锁的函数。它的作用是释放一个已经初始化的读写锁变量所占用的资源。

函数原型:

c复制代码运行
int pthread_rwlock_destroy(pthread_rwlock_t *rwlock);

参数说明:

  • rwlock:指向要销毁的读写锁变量的指针。

返回值:

  • 成功时,返回0;
  • 失败时,返回一个非零的错误码。

pthread_rwlock_rdlock

pthread_rwlock_rdlock() 是一个用于获取读锁定的函数。它的作用是尝试获取一个读写锁的读锁定,如果锁已经被写锁定或者有其他线程正在等待获取写锁定,则当前线程会进入阻塞状态,直到获取到读锁定为止。

函数原型:

int pthread_rwlock_rdlock(pthread_rwlock_t *rwlock);

参数说明:

  • rwlock:指向要获取读锁定的读写锁变量的指针。

返回值:

  • 成功时,返回0;
  • 失败时,返回一个非零的错误码。

pthread_rwlock_wrlock

pthread_rwlock_wrlock() 是一个用于获取写锁定的函数。它的作用是尝试获取一个读写锁的写锁定,如果锁已经被其他线程获取了读锁定或者写锁定,则当前线程会进入阻塞状态,直到获取到写锁定为止。

函数原型:

int pthread_rwlock_wrlock(pthread_rwlock_t *rwlock);

参数说明:

  • rwlock:指向要获取写锁定的读写锁变量的指针。

返回值:

  • 成功时,返回0;
  • 失败时,返回一个非零的错误码。

pthread_rwlock_unlock

pthread_rwlock_unlock() 是一个用于释放读写锁的函数。它的作用是释放一个已经获取到的读写锁,使得其他线程可以获取该锁。

函数原型:

int pthread_rwlock_unlock(pthread_rwlock_t *rwlock);

参数说明:

  • rwlock:指向要释放的读写锁变量的指针。

返回值:

  • 成功时,返回0;
  • 失败时,返回一个非零的错误码。

pthread_rwlock_tryrdlock

pthread_rwlock_tryrdlock() 是一个用于尝试获取读锁定的函数。它的作用是尝试获取一个读写锁的读锁定,如果锁已经被其他线程获取了写锁定,则当前线程不会进入阻塞状态,而是立即返回错误码。

函数原型:

int pthread_rwlock_tryrdlock(pthread_rwlock_t *rwlock);

参数说明:

  • rwlock:指向要尝试获取读锁定的读写锁变量的指针。

返回值:

  • 成功时,返回0;
  • 失败时,返回一个非零的错误码。

pthread_rwlock_trywrlock

pthread_rwlock_trywrlock() 是一个用于尝试获取写锁定的函数。它的作用是尝试获取一个读写锁的写锁定,如果锁已经被其他线程获取了读锁定或写锁定,则当前线程不会进入阻塞状态,而是立即返回错误码。

函数原型:

int pthread_rwlock_trywrlock(pthread_rwlock_t *rwlock);

参数说明:

  • rwlock:指向要尝试获取写锁定的读写锁变量的指针。

返回值:

  • 成功时,返回0;
  • 失败时,返回一个非零的错误码。

 


                       感谢你耐心的看到这里ღ( ´・ᴗ・` )比心,如有哪里有错误请踢一脚作者o(╥﹏╥)o! 

                                       

                                                                        给个三连再走嘛~  

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

python--切片

1.切片: 切片是编程语言为有序序列(sequence)准备的,用来切割或者截取某个片段 一个完整的切片是包含三个参数和两个冒号" : " ,用于分隔三个参数(start_index、end_index、step)。当只有一个“:”时,默认第…

java设计模式之适配器模式

适配器模式概述 众所周知,我们国家的生活用电的电压是220V,而笔记本电脑、手机等电子设备的工作电压没有这么高,为了使笔记本、手机等设备可以使用220V的生活用电,就需要使用电源适配器(ACAdapter),也就是人们常说的充电器或变压器,有了这个电源适配器,原本不能直接工作…

2024室内设计和建筑必须知道的十大3D渲染趋势!

2023年对建筑圈是非常不平凡的一年,高清视频渲染、元宇宙全覆盖、AI模型大爆发.....不断发展的 3D 数字技术世界正迅速重塑建筑设计行业。 2024年,室内设计和建筑设计领域在3D渲染方面又将迎来怎样的变革?以下十大3D渲染趋势,你不…

代码随想录——搜索插入位置(Leetcode35)

题目链接 class Solution {public int searchInsert(int[] nums, int target) {int len nums.length;int left 0;int right len - 1;int index -1;while(left < len / 2){if(nums[left] target || target < nums[left]){index left;break;}else{left;}if(nums[ri…

详解 WebWorker 的概念、使用场景、示例

前言 提到 WebWorker&#xff0c;可能有些小伙伴比较陌生&#xff0c;不知道是做什么的&#xff0c;甚至不知道使用场景&#xff0c;今天这篇文章就带大家一起简单了解一下什么是 webworker&#xff01; 概念 WebWorker 实际上是运行在浏览器后台的一个单独的线程&#xff0…

opengl草稿复习,承上启下

目录 1、链接文件夹中的cpp 2、链接资源到输出目录 3、多编译目标 4、cmakelist添加库 4、添加glfw和glad 5、glfw运行 6、NDC、VBO、VAO 7、渐变三角形 8、渲染两个三角形 9、渲染两个三角形&#xff0c;同时基于原来颜色进行渐变 1、链接文件夹中的cpp cmake_minimu…

跨站脚本攻击

跨站脚本攻击又称XSS攻击&#xff0c;是代码注入攻击的一种。利用XSS漏洞&#xff0c;攻击者可以窃取Cookies或劫持会话&#xff0c;或注入恶意 HTML 或 JavaScript 代码到页面中&#xff0c;又或者将当前页面重定向至一个攻击者搭建的恶意网站。XSS漏洞的产生多是因为网站开发…

Java 枚举(概念+枚举的使用+源码分析)

文章目录 一、枚举1.概念2.使用1.switch语句2.Enum类中的方法3.枚举无法反射 一、枚举 1.概念 将一组常量组织到一起&#xff0c;统一进行管理避免了定义常量时&#xff0c;可能发生的歧义枚举更加安全枚举不可继承&#xff0c;无法扩展 public enum TestEnum {//枚举对象&am…

第四届数字信号与计算机通信国际学术会议(DSCC 2024)

#高录用&#xff0c;稳检索# #高校背书&#xff0c;更可靠# DSCC 2024已通过SPIE出版社审核&#xff0c;ISSN号已确定&#xff1a;ISSN: 0277-786X&#xff0c;往届均已见刊EI检索&#xff01; 第四届数字信号与计算机通信国际学术会议&#xff08;DSCC 2024&#xff09; 2024 …

ROS 2边学边练(2)-- 咱也玩玩Turtlesim

同ROS 1一样&#xff0c;Turtlesim(小海龟)例程往往是大家首次熟悉ROS世界的唯一不二之选&#xff08;如同刚接触编程的同学&#xff0c;老师会让大家打出“Hello World”的道理一样&#xff09;&#xff0c;很多教学视频及书籍也同样如此&#xff0c;为何&#xff1f;麻雀虽小…

跨境必看的TikTok养号保姆式教程

TikTok养号的重要性不必多少&#xff0c;不仅可以在创号初期保障账号安全&#xff0c;后期的账号流量也需要以前期养好账号为前提。下面就给大家分享如何养号的真实操作攻略&#xff01; 一、为什么要养号 &#xff08;1&#xff09;提高系统推荐精准度 系统不了解新账户人设…

LangChain核心概念与组件

Chains Chains可以让你按照一定的顺序和逻辑来执行不同的任务。Chains有以下四种类型&#xff1a; 类型作用LLMChain用于在语言模型周围添加一些功能的简单Chain&#xff0c;它由一个PromptTemplate和一个语言模型&#xff08;LLM或chat model&#xff09;组成&#xff0c;它…

初识C++(二)引用,内联函数,auto

目录 1.引用的概念与用法&#xff1a; 1.1引用特性&#xff1a; 1.2使用场景 1.2.1做参数 1.3传值、传引用效率比较 1.4引用做返回值 1.5引用和指针的对比 2.内联函数 3.auto关键字 4. 基于范围的for循环(C11) 5.指针空值nullptr(C11) 1.引用的概念与用法&#xff1a;…

记录 AI绘图 Stable Diffusion的本地安装使用,可搭建画图服务端

开头 最近刷短视频看到了很多关于AI绘图&#xff0c;Midjourney&#xff0c;gittimg.ai&#xff0c;Stable Diffusion等一些绘图AI工具&#xff0c;感受到了AI绘画的魅力。通过chatGPT生成关键词再加上绘图工具&#xff0c;真是完美&#xff0c;文末教大家如何用gpt提词 Midj…

浮动布局与定位布局

目录 前言: 浮动布局&#xff08;Float Layout&#xff09;: 定位布局&#xff08;Positioning Layout&#xff09;: 1.传统布局: 1.1文档流布局: 1.1.1基本的布局方式: 1.1.2 块级元素: 1.1.3调整元素: 1.2浮动布局: 1.2.1浮动布局允许元素向左或向右浮动&#xff0c;使…

docker启动卡死问题排查

问题&#xff1a;输入docker ps 或则vession 卡死&#xff0c;无任何输出 排查思路如下&#xff1a; 1、查看docker状态或者日志 journalctl -u docker.service 或者 systemctl status docker 3月 20 18:23:06 dfbpmyy2 dockerd[1114]: time"2024-03-20T18:23:06.7449…

SpringBoot整合Redis:缓存击穿--互斥锁解决

&#x1f389;&#x1f389;欢迎光临&#xff0c;终于等到你啦&#x1f389;&#x1f389; &#x1f3c5;我是苏泽&#xff0c;一位对技术充满热情的探索者和分享者。&#x1f680;&#x1f680; &#x1f31f;持续更新的专栏Redis实战与进阶 本专栏讲解Redis从原理到实践 …

Python算法100例-4.5 最小公倍数

完整源代码项目地址&#xff0c;关注博主私信源代码后可获取 1.问题描述2.问题分析3.算法设计4.确定程序框架5.完整的程序 1&#xff0e;问题描述 求任意两个正整数的最小公倍数&#xff08;Least Common Multiple&#xff0c;LCM&#xff09;。 2&#xff0e;问题分析 如…

开源博客项目Blog .NET Core源码学习(12:App.Application项目结构分析)

开源博客项目Blog的App.Application项目主要定义网站页面使用的数据类&#xff0c;同时定义各类数据的增删改查操作接口和实现类。App.Application项目未安装Nuget包&#xff0c;主要引用App.Core项目的类型。   App.Application项目的顶层文件夹如下图所示&#xff0c;下面逐…

【Java程序设计】【C00352】基于Springboot的疫情隔壁酒店管理系统(有论文)

基于Springboot的疫情隔壁酒店管理系统&#xff08;有论文&#xff09; 项目简介项目获取开发环境项目技术运行截图 项目简介 项目获取 &#x1f345;文末点击卡片获取源码&#x1f345; 开发环境 运行环境&#xff1a;推荐jdk1.8&#xff1b; 开发工具&#xff1a;eclipse以…