我是靠谱客的博主 超级滑板,最近开发中收集的这篇文章主要介绍linux信号量并发控制,Linux 并发控制(互斥锁,自旋锁,信号量),觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

Linux 并发控制

在linux驱动开发中,由于驱动模块有可能被多个线程同时访问,会导致驱动模块中的变量互相影响,则需要对驱动模块中的资源进行访问控制。

在常用的linux驱动开发中,常用的并发控制有自旋锁和信号量。Linux内核中大部分用到的信号量都是互斥锁,所以主要总结自旋锁和互斥锁。

1、  信号量

信号量是一个整型值,结合一对函数,一个将进入临界区的进程将调用相关信号量的sem,如果信号量的值大于0,这个值将减一并且继续进程。相反,如果信号量的值是0(或者更小),进程必须等待别的进程释放信号量,解锁信号量通过调用相应函数完成,这个函数会增加信号量的值,并且。如果需要,可以唤醒等待的进程。

信号量是一种睡眠锁。如果有一个任务试图获得一个已被持有的信号量时,信号量会将其推入等待队列,然后让其睡眠。这时处理器获得自由去执行其它代码。当持有信号量的进程将信号量释放后,在等待队列中的一个任务将被唤醒,从而便可以获得这个信号量。

头文件:

1)  定义信号量:

struct semaphore sem;

2)  初始化信号量 :

static inline void sema_init(struct semaphore *sem, int val); //设置sem为val

#define init_MUTEX(sem) sema_init(sem, 1) //初始化一个用户互斥的信号量sem设置为1

#define init_MUTEX_LOCKED(sem) sema_init(sem, 0) //初始化一个用户互斥的信号量sem设置为0

定义和初始化可以一步完成:

DECLARE_MUTEX(name); //该宏定义信号量name并初始化1

DECLARE_MUTEX_LOCKED(name); //该宏定义信号量name并初始化0

3)  获取信号量:

void down(struct semaphore *sem)

获取信号量,如果信号量为0(即无法获得信号量)则该线程睡眠,否则获取信号量,信号量减1.

int down_interruptible(struct semaphore *sem)

与down()功能类似,但是前者不能被信号打断,后者能被信号打断(暂还不懂,后续再研究)

int down_killable(struct semaphore *sem);

与down()功能类似,后者能被kill信号打断。

int down_trylock(struct semaphore *sem)

尝试获得信号量,如果获得则返回0,如果不能获得则返回非0值,不会导致线程睡眠,可用在中断上下文中

4)  释放信号量

void up(struct semaphore *sem); //释放信号量sem,唤醒等待者

由于信号量能够导致调用者睡眠,因此不能在中断上下文使用。(详细的再研究)

2、  互斥锁

互斥锁也就是信号量只能被一个线程所拥有,即信号量的值只能使0和1。

如1所示,定义与信号量方式相同

初始化互斥锁

init_MUTEX(sem) //将互斥锁的值设置为1,见上

init_MUTEX_LOCKED(sem) //将互斥锁的值设置为0

其他操作与信号量操作相同。

3、  自旋锁

自旋锁与互斥锁一样,都是让锁只能在一个调用者手上,区别在于如果得不到锁,互斥锁会让调用者睡眠,而自旋锁调用者则会一直循环查看能否得到锁,即查看锁的拥有者是否释放了锁。类似于原地旋转,因此被称为自旋锁。

由于自旋锁不能使调用者睡眠,因此自旋锁不能被归为信号量。不会导致睡眠,因此自旋锁可以用在中断上下文以及进程上下文中。

由于自旋锁是不停循环,该线程依旧在运行,因此自旋锁适合资源只需保持很短时间的情况。

1)  定义自旋锁

spinlock_t spin;

2)  初始化自旋锁

spin_lock_init(lock);

3)  获得自旋锁

spin_lock(lock);

//成功获得自旋锁立即返回,否则自旋在那里直到该自旋锁的保持者释放

spin_trylock(lock);

//成功获得自旋锁立即返回真,否则返回假,而不是像上一个那样"在原地打转"

4)  释放自旋锁

spin_unlock(lock);

5)  使用代码

spinlock_t lock;

spin_lock_init(&lock);

spin_lock (&lock);

....//临界资源区

spin_unlock(&lock);

自旋锁不能递归使用,即只有一个线程使用锁,自己释放自己的锁。而不是不同线程互相释放锁。这样会可能会导致线程永远得不到锁。

最后

以上就是超级滑板为你收集整理的linux信号量并发控制,Linux 并发控制(互斥锁,自旋锁,信号量)的全部内容,希望文章能够帮你解决linux信号量并发控制,Linux 并发控制(互斥锁,自旋锁,信号量)所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(42)

评论列表共有 0 条评论

立即
投稿
返回
顶部