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

一、同步互斥机制

应用场景:多线程的时候。当多个执行单元同时被执行,处理的是同一个资源时,就会导致竞态,这个时候就需要用同步或者互斥的方法来解决竞态。

线程和进程的区别:进程是拥有资源的最小单位,线程是参与调度的最小单位。

执行单元:进程、线程、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    自旋锁结构体指针 

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

三、互斥体

头文件: <linux/mutex.h>
数据类型: struct mutex

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

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

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

发布了1 篇原创文章 · 获赞 1 · 访问量 23

猜你喜欢

转载自blog.csdn.net/weixin_46097899/article/details/104526364