Linux内核并发机制

这套机制是特别为内核态线程准备的。它们是用在内核中的并发机制,提供内核代码执行中的并发性。

原子操作

Linux提供了一组操作以保证对变量的原子操作。原子操作执行时不会被打断或被干涉。在单处理器上,线程一旦启动原子操作,则从操作开始到结束的这段时间内,线程不能被中断。

Linux定义了两种原子操作,一种是针对整数变量的整数操作,一种是针对位图中某一位的位图操作。

原子整数操作,定义了一个特殊的数据类型atomic_t,原子整数操作仅能用在这个数据类型上,其他操作不允许用在这个数据类型上。
这里写图片描述

原子位图操作由指针变量指定任意一块内存区域的位序列中的某一位。
这里写图片描述

自旋锁

在Linux中保护临界区最常见的技术使自旋锁。在同一时刻,只有一个线程能获得自旋锁。其他任何企图获得自旋锁的线程将一直进行尝试(自旋),直到获得了该锁。
这里写图片描述

这里写图片描述

基本的自旋锁有如下四个版本:

  • 普通(plain):如果临界区代码不被中断处理程序执行,或在中断禁用的情况下,那么可以使用普通自旋锁,它不会影响当前处理器的中断状态。
  • _irq:如果中断一直被启用,那么可以使用这种自旋锁;
  • _irqsave:如果不知道在执行时间内中断是否启用,那么可以使用这个版本。
  • _bh:当发生中断时,相应的中断处理器只处理最少量的必要工作。

信号量

在内核内部,Linux提供了供自己使用的信号量的具体实现,即在内核中的代码能够调用内核信号量。内核的信号量不能通过系统调用直接被用户程序访问。内核信号量是作为内核内部函数实现的,因此比用户可见的信号量更加高效。
Linux在内核中提供了三种信号量:二元信号量、计数信号量和读者-写者信号量。
这里写图片描述

计数信号量使用sema_init函数初始化,该函数给信号量命名并赋初值。二元信号量在Linux中也称为MUTEX(互斥信号量),它使用init_MUTEX和init_MUTEX_LOCKED函数初始化,这两个函数分别将信号量初始化为1和0。

Linux提供了三种版本的down(semWait)操作

  • down函数对应于传统的semWait操作。也就是线程测试信号量,如果信号量不可用就阻塞。当在信号量上对应的up操作发生时,线程就会被唤醒。
  • down_interrupible函数允许因down操作被阻塞的线程在次期间接收并响应内核信号。
  • down_trylock函数可在不被阻塞的同时获得信号量。如果信号量可用,就可以获得它。否则函数返回一个非零值,而不会阻塞该线程。

读者-写者信号量 读者-写者信号量把用户分为读者和写者:它允许多个并发的读者(没有写者),但仅允许一个写者(没有读者)。事实上,对于读者使用的是一个计数信号量,而对于写者使用的是二元信号量(MUTEX)。

小结

死锁是指一组争用系统资源或相互通信的进程被阻塞的现象。这种阻塞是永久的。

处理死锁通常有三种方法:预防、检测和避免。死锁预防通过确保死锁的一个必要条件不会满足,保证不会发生死锁。如果操作系统总是同意资源请求,则需要进行死锁检测。操作系统必须周期性地检查死锁,并采取行动打破死锁。死锁避免涉及分析新的资源请求,以确定它是否会导致死锁,并且只有当不可能发生死锁时才同意该请求。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值