在nginx里面,定义了一个spinlock,来同步父子进程间的共享内存操作
- #define ngx_shmtx_lock(mtx) ngx_spinlock((mtx)->lock, ngx_pid, 1024)
- void ngx_spinlock(ngx_atomic_t *lock, ngx_atomic_int_t value, ngx_uint_t spin)
- {
- #if (NGX_HAVE_ATOMIC_OPS)
- ngx_uint_t i, n;
- for ( ;; ) {
- //__sync_bool_compare_and_swap(lock, old, set)
- //这是原子操作
- //尝试把lock的值设置成value,如果不为0就说明已经有其他进程获取了该锁
- if (*lock == 0 && ngx_atomic_cmp_set(lock, 0, value)) {
- //获取锁成功
- return;
- }
- if (ngx_ncpu > 1) {
- //spin=1024,每次shift一位
- for (n = 1; n < spin; n <<= 1) {
- //n=1,2,4,8,16,32,64,128 ...
- //每次等待时间增加一倍
- for (i = 0; i < n; i++) {
- //__asm__(".byte 0xf3, 0x90")
- //__asm__("pause")
- //等待一段时间
- ngx_cpu_pause();
- }
- //等待一段时间再去尝试获取锁
- if (*lock == 0 && ngx_atomic_cmp_set(lock, 0, value)) {
- //获取锁成功
- return;
- }
- }
- }
- //试了这么多次,还是没有获取锁,那就休息一下吧
- //sched_yield()
- //usleep(1)
- ngx_sched_yield();
- }
- #else
- #if (NGX_THREADS)
- #error ngx_spinlock() or ngx_atomic_cmp_set() are not defined !
- #endif
- #endif
- }