欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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

程序员文章站 2022-03-22 20:22:35
...

一、同步互斥机制

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

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

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

互斥体的上锁和解锁:
同步互斥机制及自旋锁、互斥体
运行结果:
同步互斥机制及自旋锁、互斥体

相关标签: 驱动程序