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

linux学习第30天(线程同步和锁)

线程同步

        协同步调,对公共区域数据按序访问。防止数据混乱,产生与时间有关的错误。

数据混乱的原因

  1. 资源共享(独享资源则不会)

  2. 调度随机(意味着数据访问会出现竞争)

  3. 线程间缺乏必要同步机制

锁的使用

        建议锁!对公共数据进行保护。所有线程【应该】在访问公共数据前先拿锁再访问。但,锁本身不具备强制性。

主要应用函数:

    pthread_mutex_init       函数:创建锁

    pthread_mutex_destory    函数:初始化

    pthread_mutex_lock       函数:加锁

    pthread_mutex_trylock    函数:

    pthread_mutex_unlock     函数:解锁

以上5个函数的返回值都是:成功返回0,失败返回错误号

、、、、、、、、、、、

pthread_mutex_t 类型,其本质是一个结构体。为简化理解,应用时可忽略其实现细节,简单当成整数看待

pthread_mutex_t mutex;变量mutex只有两种取值:0,1

、、、、、、、

使用mutex(互斥量、互斥锁)一般步骤:

    pthread_mutex_t 类型。

    1. pthread_mutex_t lock;  创建锁

    2  pthread_mutex_init; 初始化      1

    3. pthread_mutex_lock;加锁      1-- --> 0

    4. 访问共享数据(stdout)   

    5. pthrad_mutext_unlock();解锁     0++ --> 1

    6. pthead_mutex_destroy;销毁锁

、、、、、、、、、、、

int pthread_mutex_init(pthread_mutex_t *restrict mutex,

const pthread_mutexattr_t *restrict attr)

这里的restrict关键字,表示指针指向的内容只能通过这个指针进行修改

restrict关键字:

    用来限定指针变量。被该关键字限定的指针变量所指向的内存操作,必须由本指针完成。

初始化互斥量:

       pthread_mutex_t mutex;

       1. pthread_mutex_init(&mutex, NULL);              动态初始化。

       2. pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;  静态初始化。

例子:借助互斥锁管理共享数据实现同步

未加锁

加锁

互斥锁使用技巧

注意事项:

       尽量保证锁的粒度, 越小越好。(访问共享数据前,加锁。访问结束【立即】解锁。)

       互斥锁,本质是结构体。 我们可以看成整数。 初值为 1。(pthread_mutex_init() 函数调用成功。)

       加锁: --操作, 阻塞线程。

       解锁: ++操作, 唤醒阻塞在锁上的线程。

       try锁:尝试加锁,成功--。失败,返回。同时设置错误号 EBUSY

死锁

是使用锁不恰当导致的现象:

       1. 对一个锁反复lock。

       2. 两个线程,各自持有一把锁,请求另一把。

第一种情况,反复加锁;

第二种情况,1先拿A锁,2先拿B锁,1又要拿B,2又要拿A,就都在这阻塞等待。

读写锁

特性:

  1. 读写锁是“写模式加锁”时, 解锁前,所有对该锁加锁的线程都会被阻塞。
  2. 读写锁是“读模式加锁”时, 如果线程以读模式对其加锁会成功;如果线程以写模式加锁会阻塞。
  3. 读写锁是“读模式加锁”时, 既有试图以写模式加锁的线程,也有试图以读模式加锁的线程。那么读写锁会阻塞随后的读模式锁请求。优先满足写模式锁。读锁、写锁并行阻塞,写锁优先级高

        读写锁也叫共享-独占锁。当读写锁以读模式锁住时,它是以共享模式锁住的;当它以写模式锁住时,它是以独占模式锁住的。写独占、读共享。

        读写锁非常适合于对数据结构读的次数远大于写的情况。

、、、、、、、、、、、、

    锁只有一把。以读方式给数据加锁——读锁。以写方式给数据加锁——写锁。

    读共享,写独占。

    写锁优先级高。(两个写,一个读,等两个写结束再读)

    相较于互斥量而言,当读线程多的时候,提高访问效率

    pthread_rwlock_t  rwlock;

    pthread_rwlock_init(&rwlock, NULL);

    pthread_rwlock_rdlock(&rwlock);    try

    pthread_rwlock_wrlock(&rwlock);    try

    pthread_rwlock_unlock(&rwlock);

    pthread_rwlock_destroy(&rwlock);

以上函数都是成功返回0,失败返回错误号。

pthread_rwlock_t 类型    用于定义一个读写锁变量

pthread_rwlock_t  rwlock

例子

3个线程不定时 "全局资源,5个线程不定时 "同一全局资源

http://www.dtcms.com/a/275890.html

相关文章:

  • WordPress Ads Pro Plugin本地文件包含漏洞(CVE-2025-4380)
  • 计算机毕业设计springboot服装工厂移动报表软件设计 基于SpringBoot的服装企业移动端数据可视化系统 面向服装制造行业的移动报表与公告发布平台
  • 微服务环境下的灰度发布与金丝雀发布实战经验分享
  • 多路选择器的学习
  • 《Java Web程序设计》实验报告六 JSP+JDBC+MySQL实现登录注册
  • 【飞算JavaAI】一站式智能开发,驱动Java开发全流程革新
  • 20250712-1-Kubernetes 监控与日志管理-K8s日志管理与维护_笔记
  • Go语言中的Options模式
  • 【Go + Gin 实现「双 Token」管理员登录】
  • Linux驱动08 --- 数据库
  • MCU芯片的功能安全机制E2E的基本原理和应用实现
  • 解锁C++数据结构:开启高效编程之旅
  • IDEA+Eclipse+Lombok无效问题排查
  • Java 之字符串 --- String 类
  • 电脑上如何查看WiFi密码
  • 什么是Jaccard 相似度(Jaccard Similarity)
  • 蓝牙调试抓包工具--nRF Connect移动端 使用详细总结
  • 日志不再孤立!用 Jaeger + TraceId 实现链路级定位
  • 程序在计算机中如何运行?——写给编程初学者的指南
  • 12.使用VGG网络进行Fashion-Mnist分类
  • Jenkins+Gitee+Docker容器化部署
  • 三步定位 Git Push 403:从日志到解决
  • 【深度剖析】致力“四个最”的君乐宝数字化转型(下篇:转型成效5-打造数字化生存能力探索可持续发展路径)
  • 【Datawhale AI夏令营】mcp-server
  • LeetCode 每日一题 2025/7/7-2025/7/13
  • 1. 好的设计原则
  • XCTF-Mary_Morton双漏洞交响曲:格式化字符串漏洞泄露Canary与栈溢出劫持的完美配合
  • 【2024CSP-J初赛】阅读程序(2)试题详解
  • 剑指offer57_和为S的两个数字
  • 深入详解:决策树在医学影像脑部疾病诊断中的应用与实现