信号量原理 与锁的原理
一、 什么是信号量?
信号量(semaphore)的数据结构为一个值和一个指针,指针指向等待该信号量的下一个进程。信号量的值与相应资源的使用情况有关。
当它的值大于0时,表示当前可用资源的数量;
当它的值小于0时,其绝对值表示等待使用该资源的进程个数。
p操作(wait):申请一个单位资源,进程进入
wait(S){
while(s<=0) ; //如果没有资源则会循环等待;
S--;
}
v操作(signal):释放一个单位资源,进程出来
signal(S){
S++ ;
}
signal(S){
S++ ;
}
二、lock和unlock实现原理
lock() {
if(mutex > 0){
mutex = 0;
return 0;
}else{
goto lock; // 挂起等待
}
ulock
ulock (){
mutex = 1; // 唤醒等待 Mutex 的线程
return 0;
}
在Linux下,信号量和线程互斥锁的实现都是通过futex系统调用。
Futex(快速用户区互斥的简称)是一个在Linux上实现锁定和构建高级抽象锁如信号量和POSIX互斥的基本工具。它们第一次出现在内核开发的2.5.7版;其语义在2.5.40固定下来,然后在2.6.x系列稳定版内核中出现。
Futex 是fast userspace mutex的缩写,意思是快速用户空间互斥体。Linux内核把它们作为快速的用户空间的锁和信号量的预制构件提供给开发者。Futex非常基础,借助其自身的优异性能,构建更高级别的锁的抽象,如POSIX互斥体。大多数程序员并不需要直接使用Futex,它一般用来实现像NPTL这样的系统库。
Futex 由一块能够被多个进程共享的内存空间(一个对齐后的整型变量)组成;这个整型变量的值能够通过汇编语言调用CPU提供的原子操作指令来增加或减少,并且一个进程可以等待直到那个值变成正数。Futex 的操作几乎全部在应用程序空间完成;只有当操作结果不一致从而需要仲裁时,才需要进入操作系统内核空间执行。这种机制允许使用 futex 的锁定原语有非常高的执行效率:由于绝大多数的操作并不需要在多个进程之间进行仲裁,所以绝大多数操作都可以在应用程序空间执行,而不需要使用(相对高代价的)内核系统调用。
Futex保存在用户空间的共享内存中,并且通过原子操作进行操作。在大部分情况下,资源不存在争用的情况下,进程或者线程可以立刻获得资源成功,实际上就没有必要调用系统调用,陷入内核了。实际上,futex的作用就在于减少系统调用的次数,来提高系统的性能。
参考 :
https://blog.csdn.net/u011244446/article/details/52574369 Linux 互斥锁、原子操作实现原理
https://www.cnblogs.com/sylz/p/6030201.html
http://c.biancheng.net/view/1231.html 互斥锁的原理及作用
https://blog.csdn.net/summy_J/article/details/72756926 linux线程互斥与同步(part1)—互斥锁(mutex)的原理及其实现机制
https://www.jianshu.com/p/5785f179778a 信号量机制及几个经典例题