同步互斥机制及自旋锁、互斥体

Zahirah ·
更新时间:2024-09-21
· 918 次阅读

一、同步互斥机制 应用场景:多线程的时候。当多个执行单元同时被执行,处理的是同一个资源时,就会导致竞态,这个时候就需要用同步或者互斥的方法来解决竞态。 线程和进程的区别:进程是拥有资源的最小单位,线程是参与调度的最小单位。 执行单元:进程、线程、SMP(对称多处理器) 资源:软件资源或者是硬件资源 并发:多个执行单元同时被执行。 竞态:多个执行单元同时被执行,处理的是同一个资源,就会导致竞态。 临界区:对资源进程操作的代码区 临界资源:可能会被多个执行单元同时访问并操作的资源

导致竞态原因:

1.多进程同时访问操作临界资源(进程和抢占它的进程之间会导致竞态) 2.进程和中断 3.对称多处理器

解决竞态的方法:

同步:强调的是顺序性 互斥:强调的是排他性

具体的解决方法:

1.屏蔽中断 2.自旋锁 3.原子操作 4.互斥体(互斥锁) 5.信号量 二、自旋锁

头文件:linux/spinlock.h
自旋锁数据类型:spinlock_t

锁机制,完成互斥操作,和互斥锁类似

上自旋锁;
临界区;
解自旋锁;

自旋锁上锁后,会屏蔽掉进程抢占,如果进程1在临界区出现进程调度的相关函数(例如:sleep),就相当于放弃了CPU的执行权。这时,操作系统就会去调度其他进程(进程2),进程2在执行的时候需要进行上锁,但是进程1还没有释放锁,进程2就获取不到锁,会进入自旋状态,导致CPU会被100%占用。如果CPU是单核的,sleep函数结束后,进程1由于进程2(进入自旋状态)把CPU资源全部占用,解锁永远不会执行,就会导致死锁。

注意:尤其是在单核CPU的情况下,不能够在自旋锁保护的临界区出现关于进程调度相关函数。

相关函数:
需要定义一个flag标志位,用来判断是否为第一次打开 spin_lock_init(spinlock_t *lock) 功能:初始化自旋锁 参数: @lock 自旋锁结构体指针 void spin_lock(spinlock_t *lock) 功能:自旋锁上锁 参数: @lock 自旋锁结构体指针 int spin_trylock(spinlock_t *lock) 功能:自旋锁上锁 参数: @lock 自旋锁结构体指针 特点:如果上锁失败,错误返回 void spin_unlock(spinlock_t *lock) 功能:自旋锁解锁 参数: @lock 自旋锁结构体指针

自旋锁的初始化:
在这里插入图片描述
自旋锁的上锁与解锁:
在这里插入图片描述
标志位的定义及加减操作函数:
在这里插入图片描述
运行结果:
在这里插入图片描述

三、互斥体

头文件:
数据类型: struct mutex

互斥体上锁
临界区
互斥体解锁

相关函数: mutex_init(struct mutex *mutex) 功能:初始化互斥体 参数: @mutex 互斥体结构体指针 void mutex_lock(struct mutex *lock) 功能:互斥体上锁 参数: @lock 互斥体结构体指针 特点:互斥体上锁失败,会导致应用层进程休眠 void mutex_unlock(struct mutex *lock) 功能:互斥体解锁 参数: @lock 互斥体结构体指针

互斥体的上锁和解锁:
在这里插入图片描述
运行结果:
在这里插入图片描述


作者:weixin_46097899



互斥体 互斥 自旋锁 自旋

需要 登录 后方可回复, 如果你还没有账号请 注册新账号