Open vaynedu opened 5 years ago
volatile 关键字告诉C编译器不要优化,就看是否支持volatile关键字,如果不支持,nginx模拟实现支持,这个需要使用到内联汇编, 需要使用到asm 关键字
a) 其实锁很简单,也很好理解,锁只是一种同步的方式,保证资源的安全访问。怎么可以做到这一点呢,多进程环境,大家去共享内存去获取这个变量,哪个进程获取到这个变量,就相当于谁有锁, 谁就有权利访问这个资源。 b) 自旋锁: 进程获取不到锁就一直循环等待,之道获取到锁为止。nginx在自旋锁中使用了PAUSE指令用来提升CPU的性能,节省电量。 c) 这部分代码比较简单,一目了然
1.文件锁的原理就是在磁盘上创建一个文件(操作系统创建一个文件描述符),然后多个进程竞争去获取这个文件的访问权限,因此同一时刻只有一个进程能够访问临界区。 2.文件锁创造一个文件之后,会直接删除这个文件,只是用其fd (内核的信息结构),后面通过fcntl函数设置fd的属性,控制加解锁。 3.效率低下,不建议使用
支持信号量只会影响阻塞进程的ngx_shmtx_lock方法持有锁的方式。当不支持信号量,就是自旋锁,支持信号量时,ngx_shmtx_lock将spin指定的一段时间内自旋等待其他CPU释放锁,如果达到spin的上限还没有获得锁,那么将会sem_wait使得当前进程进入睡眠状态,等待其他进程释放锁内核唤醒这个进程。nginx在spin上限之后如果还获得不了锁,很可能强制获得锁。 反正nginx作为高性能服务器,容不得半点阻塞,否则的很多连接就饿死了。 目前不清楚nginx到底是什么强制获得锁呢?猜测是不是特别高的优先级。疑问 备注:信号量使用不好很可能导致进程睡眠 todo: 信号量现在基本没有怎么使用,对这个不怎么清楚。
个人觉得: 原子操作 + 信号量 和 自旋锁都可以吧, nginx自旋锁很适合这种简单的场景,表现应该不会比 原子操作 + 信号量 实现方式差(虽然说自旋锁会盲目的旋转等待)
nginx互斥锁有3中实现方式:自旋锁(原子操作)、文件锁、原子操作+信号量
一. 自旋锁(原子操作)
1. 如何判断当前操作系统是否支持原子操作?
volatile 关键字告诉C编译器不要优化,就看是否支持volatile关键字,如果不支持,nginx模拟实现支持,这个需要使用到内联汇编, 需要使用到asm 关键字
2.nginx的自旋锁如何实现?
a) 其实锁很简单,也很好理解,锁只是一种同步的方式,保证资源的安全访问。怎么可以做到这一点呢,多进程环境,大家去共享内存去获取这个变量,哪个进程获取到这个变量,就相当于谁有锁, 谁就有权利访问这个资源。 b) 自旋锁: 进程获取不到锁就一直循环等待,之道获取到锁为止。nginx在自旋锁中使用了PAUSE指令用来提升CPU的性能,节省电量。 c) 这部分代码比较简单,一目了然
二. 文件锁
1.文件锁的原理就是在磁盘上创建一个文件(操作系统创建一个文件描述符),然后多个进程竞争去获取这个文件的访问权限,因此同一时刻只有一个进程能够访问临界区。 2.文件锁创造一个文件之后,会直接删除这个文件,只是用其fd (内核的信息结构),后面通过fcntl函数设置fd的属性,控制加解锁。 3.效率低下,不建议使用
三、原子操作+信号量
支持信号量只会影响阻塞进程的ngx_shmtx_lock方法持有锁的方式。当不支持信号量,就是自旋锁,支持信号量时,ngx_shmtx_lock将spin指定的一段时间内自旋等待其他CPU释放锁,如果达到spin的上限还没有获得锁,那么将会sem_wait使得当前进程进入睡眠状态,等待其他进程释放锁内核唤醒这个进程。nginx在spin上限之后如果还获得不了锁,很可能强制获得锁。 反正nginx作为高性能服务器,容不得半点阻塞,否则的很多连接就饿死了。 目前不清楚nginx到底是什么强制获得锁呢?猜测是不是特别高的优先级。疑问 备注:信号量使用不好很可能导致进程睡眠 todo: 信号量现在基本没有怎么使用,对这个不怎么清楚。
个人觉得: 原子操作 + 信号量 和 自旋锁都可以吧, nginx自旋锁很适合这种简单的场景,表现应该不会比 原子操作 + 信号量 实现方式差(虽然说自旋锁会盲目的旋转等待)