没有合适的资源?快使用搜索试试~ 我知道了~
温馨提示
内容概要:本文详细介绍了Linux系统编程中的线程同步机制,涵盖同步的基本概念及其在编程中的具体实现。文章首先解释了同步的概念,即确保多个控制流在操作共享资源时按预定顺序执行,避免数据混乱。接着深入探讨了互斥量(mutex)、读写锁(read-write lock)、条件变量(condition variable)以及信号量(semaphore)四种主要的线程同步工具,包括它们的工作原理、应用场景及相关的API函数。文中通过多个实例演示了如何利用这些工具解决实际问题,如经典的生产者消费者模型。此外,还讨论了死锁现象及其产生原因,并提供了相应的预防措施。 适合人群:有一定编程经验,尤其是对Linux系统编程感兴趣的开发者;从事多线程编程工作的软件工程师。 使用场景及目标:①理解线程同步的重要性及其实现方式;②掌握互斥量、读写锁、条件变量和信号量的具体用法;③学会识别并解决多线程编程中可能出现的数据竞争和死锁问题;④提高多线程应用程序的性能和可靠性。 其他说明:阅读时建议结合实际代码进行练习,加深对各同步机制的理解。对于互斥量、读写锁等工具,要注意锁的粒度尽量小,以减少不必要的阻塞。同时,条件变量可以有效减少线程间的无效竞争,而信号量则提供了比互斥锁更灵活的资源管理方式。
资源推荐
资源详情
资源评论





























同步概念
所谓同步,即同时起步,协调一致。不同的对象,对“同步”的理解方式略有不同。如,设备同步,是指在两
个设备之间规定一个共同的时间参考;数据库同步,是指让两个或多个数据库内容保持一致,或者按需要部分保持
一致;文件同步,是指让两个或多个文件夹里的文件保持一致。等等
而,编程中、通信中所说的同步与生活中大家印象中的同步概念略有差异。“同”字应是指协同、协助、互相
配合。主旨在协同步调,按预定的先后次序运行。
线程同步
同步即协同步调,按预定的先后次序运行。
线程同步,指一个线程发出某一功能调用时,在没有得到结果之前,该调用不返回。同时其它线程为保证数据
一致性,不能调用该功能。
举例 1: 银行存款 5000。柜台,折:取 3000;提款机,卡:取 3000。剩余:2000
举例 2: 内存中 100 字节,线程 T1 欲填入全 1, 线程 T2 欲填入全 0。但如果 T1 执行了 50 个字节失去 cpu,T2 执
行,会将 T1 写过的内容覆盖。当 T1 再次获得 cpu 继续从失去 cpu 的位置向后写入 1,当执行结束,内存中的 100
字节,既不是全 1,也不是全 0。
产生的现象叫做“与时间有关的错误”(time related)。为了避免这种数据混乱,线程需要同步。
“同步”的目的,是为了避免数据混乱,解决与时间有关的错误。实际上,不仅线程间需要同步,进程间、信
号间等等都需要同步机制。
因此,所有“多个控制流,共同操作一个共享资源”的情况,都需要同步。
数据混乱原因:
1. 资源共享(独享资源则不会)
2. 调度随机(意味着数据访问会出现竞争)
3. 线程间缺乏必要的同步机制。
以上 3 点中,前两点不能改变,欲提高效率,传递数据,资源必须共享。只要共享资源,就一定会出现竞争。
只要存在竞争关系,数据就很容易出现混乱。
所以只能从第三点着手解决。使多个线程在访问共享资源的时候,出现互斥。
互斥量 mutex
Linux 中提供一把互斥锁 mutex(也称之为互斥量)。
每个线程在对资源操作前都尝试先加锁,成功加锁才能操作,操作结束解锁。
资源还是共享的,线程间也还是竞争的,
但通过“锁”就将资源的访问变成互斥操作,而后与时间有关的错误也不会再产生了。

但,应注意:同一时刻,只能有一个线程持有该锁。
当 A 线程对某个全局变量加锁访问,B 在访问前尝试加锁,拿不到锁,B 阻塞。C 线程不去加锁,而直接访问
该全局变量,依然能够访问,但会出现数据混乱。
所以,互斥锁实质上是操作系统提供的一把“建议锁”(又称“协同锁”),建议程序中有多线程访问共享资源
的时候使用该机制。但,并没有强制限定。
因此,即使有了 mutex,如果有线程不按规则来访问数据,依然会造成数据混乱。
主要应用函数:
pthread_mutex_init 函数
pthread_mutex_destroy 函数
pthread_mutex_lock 函数
pthread_mutex_trylock 函数
pthread_mutex_unlock 函数
以上 5 个函数的返回值都是:成功返回 0, 失败返回错误号。
pthread_mutex_t 类型,其本质是一个结构体。为简化理解,应用时可忽略其实现细节,简单当成整数看待。
pthread_mutex_t mutex; 变量 mutex 只有两种取值 1、0。
pthread_mutex_init 函数
初始化一个互斥锁(互斥量) ---> 初值可看作 1
int pthread_mutex_init(pthread_mutex_t *restrict mutex, const pthread_mutexattr_t *restrict attr);
参 1:传出参数,调用时应传 &mutex
restrict 关键字:只用于限制指针,告诉编译器,所有修改该指针指向内存中内容的操作,只能通过本指针完成。
不能通过除本指针以外的其他变量或指针修改
参 2:互斥量属性。是一个传入参数,通常传 NULL,选用默认属性(线程间共享)。 参 APUE.12.4 同步属性
1. 静态初始化:如果互斥锁 mutex 是静态分配的(定义在全局,或加了 static 关键字修饰),可以直接
使用宏进行初始化。e.g. pthead_mutex_t muetx = PTHREAD_MUTEX_INITIALIZER;
2. 动态初始化:局部变量应采用动态初始化。e.g. pthread_mutex_init(&mutex, NULL)

pthread_mutex_destroy 函数
销毁一个互斥锁
int pthread_mutex_destroy(pthread_mutex_t *mutex);
pthread_mutex_lock 函数
加锁。可理解为将 mutex--(或 -1),操作后 mutex 的值为 0。
int pthread_mutex_lock(pthread_mutex_t *mutex);
pthread_mutex_unlock 函数
解锁。可理解为将 mutex ++(或 +1),操作后 mutex 的值为 1。
int pthread_mutex_unlock(pthread_mutex_t *mutex);
pthread_mutex_trylock 函数
尝试加锁
int pthread_mutex_trylock(pthread_mutex_t *mutex);
加锁与解锁
lock 与 unlock:
lock 尝试加锁,如果加锁不成功,线程阻塞,阻塞到持有该互斥量的其他线程解锁为止。
unlock 主动解锁函数,同时将阻塞在该锁上的所有线程全部唤醒,至于哪个线程先被唤醒,取决于优先级、调
度。默认:先阻塞、先唤醒。
例如:T1 T2 T3 T4 使用一把 mutex 锁。T1 加锁成功,其他线程均阻塞,直至 T1 解锁。T1 解锁后,T2 T3 T4 均
被唤醒,并自动再次尝试加锁。
可假想 mutex 锁 init 成功初值为 1。lock 功能是将 mutex--。而 unlock 则将 mutex++。
lock 与 trylock:
lock 加锁失败会阻塞,等待锁释放。
trylock 加锁失败直接返回错误号(如:EBUSY),不阻塞。
剩余13页未读,继续阅读
资源评论


数研基站
- 粉丝: 66
上传资源 快速赚钱
我的内容管理 展开
我的资源 快来上传第一个资源
我的收益
登录查看自己的收益我的积分 登录查看自己的积分
我的C币 登录后查看C币余额
我的收藏
我的下载
下载帮助


最新资源
- 全国计算机等级测验一级练习题(2).docx
- 电气工程的特点以及自动化技术的发展刍议1.docx
- 电力工程建设项目管理存在的问题和精细化管理策略1.docx
- 浅析互联网+与高校学生管理工作.docx
- 首届中国互联网大学生创新创业大赛河南省选拔赛工作方案.doc
- 基于大数据分析的商业银行运营风险管理研究.docx
- 软考中级-信息系统管理工程师复习笔记(干货).docx
- 婚姻状态与网络借贷中的信用识别.docx
- 基于PLC控制的四层电梯课程设计.doc
- 东莞小学生计算机程序设计活动镇区选拔赛笔试题.doc
- 华为FusionInsight大数据平台.pdf
- 基于plc控制的机械手的方案设计书.doc
- 有线无线同时接入网络如何判断和设置优先级.doc
- 试论云计算在工程造价信息管理中的应用.docx
- 负荷预测matlab仿真报告.doc
- EXCEL辅助计算公路中桩与边桩参数的应用.docx
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈



安全验证
文档复制为VIP权益,开通VIP直接复制
