nginx自旋锁

Posted 阮減显

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了nginx自旋锁相关的知识,希望对你有一定的参考价值。

#include <stdio.h>
#include <stdint.h>
#include <unistd.h>
/*
typedef unsigned long               ngx_atomic_uint_t;
typedef volatile ngx_atomic_uint_t  ngx_atomic_t;
typedef long                        ngx_atomic_int_t;

#define ngx_atomic_cmp_set(lock, old, set)  __sync_bool_compare_and_swap(lock, old, set)
*/



#define my_unlock(lock)    *(lock) = 0


//lock: 原子变量表达的锁
//value:标志位,锁是否被某一进程占用,一般情况下为进程pid
//spin: 在多处理器系统内,当my_spinlock方法没有拿到锁时,当前进程在内核的一次调度中该方法等待其他处理器释放锁的时间 
void my_spinlock(volatile unsigned long *lock,long value,uintptr_t spin)
{
		uintptr_t i,n;
		while(1){
			//lock为0表示没有其他进程持有锁,这时将lock值设置为value,表示当前进程持有了锁 
			if(*lock == 0 && __sync_bool_compare_and_swap(lock, 0, value)){
				return;
			}
			//如果是多处理器系统
			if(sysconf(_SC_NPROCESSORS_CONF) > 1){
					for (n = 1; n < spin; n <<= 1) {
							//随着等待的次数越来越多,实际去检查锁的间隔时间越来越大
							for (i = 0; i < n; i++) {
                    __asm__ ("pause");
              }
              //检查锁是否被释放
              if (*lock == 0 && __sync_bool_compare_and_swap(lock, 0, value)) {
                    return;
              }
					}
			}
			//当前进程让出处理器,但仍然处于可执行状态
			sched_yield();
		}
}

/*

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 ( ;; ) {

        //lock为0表示没有其他进程持有锁,这时将lock值设置为value参数表示当前进程持有了锁
        if (*lock == 0 && ngx_atomic_cmp_set(lock, 0, value)) {
            return;
        }

        //如果是多处理器系统
        if (ngx_ncpu > 1) {
            for (n = 1; n < spin; n <<= 1) {
                //随着等待的次数越来越多,实际去检查锁的间隔时间越来越大
                for (i = 0; i < n; i++) {
                    ngx_cpu_pause();//告诉CPU现在处于自旋锁等待状态
                }

                //检查锁是否被释放
                if (*lock == 0 && ngx_atomic_cmp_set(lock, 0, value)) {
                    return;
                }
            }
        }

        //当前进程让出处理器,但仍然处于可执行状态
        ngx_sched_yield();
    }

#else

#if (NGX_THREADS)

#error ngx_spinlock() or ngx_atomic_cmp_set() are not defined !

#endif

#endif

}

*/

volatile unsigned long lock;

int main()
{
	fprintf(stderr,"cpu %d pid=%d\n",sysconf(_SC_NPROCESSORS_CONF),getpid());
	my_spinlock(&lock,getpid(),1024);
	fprintf(stderr,"lock %d\n",lock);
	my_unlock(&lock);
	fprintf(stderr,"lock %d\n",lock);
	return 0;

}

 

以上是关于nginx自旋锁的主要内容,如果未能解决你的问题,请参考以下文章

Java 通过原子类 AtomicStampedReference 实现自旋锁

Redis实现分布式锁(设计模式应用实战)

Redis实现分布式锁(设计模式应用实战)

Linux设备驱动程序 之 自旋锁

自旋锁原理分析

自旋锁互斥锁信号量原子操作条件变量在不同开源框架的应用