本文主要是介绍nginx自旋锁ngx_spinlock分析,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
以前也看过linux内核自旋锁的实现代码,现在工作主要是应用程序开发,对应用程序开发不是太了解,我喜欢通过看优秀的开源软件学习软件开发,之前对linux kernel感兴趣就是看内核代码,现在工作需要http,数据库,网络编程这方面的只是,我想学习http和网络编程看完nginx我想也差不多了。
void ngx_spinlock函数代码:
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 ( ;; ) {// 没有上锁则上锁,上锁成功则返回 if (*lock == 0 && ngx_atomic_cmp_set(lock, 0, value)) {return;}if (ngx_ncpu > 1) { //SMPfor (n = 1; n < spin; n <<= 1) {for (i = 0; i < n; i++) {ngx_cpu_pause();}if (*lock == 0 && ngx_atomic_cmp_set(lock, 0, value)) {return;}}}ngx_sched_yield(); // 看具体实现,任务调度或者usleep。}#else}
的一个实现。
这和linux内核的自旋锁本质是一样的,核心是在锁总线的情况下,原子完成比较和交换操作,也就是mem和newval
的比较和交换操作。如果上锁成功返回值大于O。
#define LOCK_PREFIX "lock;"
#define __sync_bool_compare_and_swap(mem, oldval, newval) \
({ __typeof (*mem) ret; \
__asm __volatile (LOCK_PREFIX "cmpxchgl %2, %1;sete %%al; movzbl %%al,%%eax" \
: "=a" (ret), "=m" (*mem) \
: "r" (newval), "m" (*mem), "a" (oldval)\
:"memory"); \
ret; })
我用cscope查找 ngx_sched_yield()函数定义,下面是查找结果。我们可以发现这个函数nginx
根据不同情况有三种实现,*nix提供usleep和sched_yield,win32是SwitchToThread()。
win32我不了解,不过看名字就知道什么意思,切换进程。我们说一下*nix的实现。
*** src/os/unix/ngx_process.h:
ngx_sched_yield[71] #define ngx_sched_yield() sched_yield()
ngx_sched_yield[73] #define ngx_sched_yield() usleep(1)
*** src/os/win32/ngx_process.h:
ngx_sched_yield[56] #define ngx_sched_yield() SwitchToThread()
打开ngx_process.h头文件
有下面几行代码。这意思就很清晰了,不多说。
#if (NGX_HAVE_SCHED_YIELD)
#define ngx_sched_yield() sched_yield()
#else
#define ngx_sched_yield() usleep(1)
#endif
*nix OS应用层提供的任务调度函数。
#include <sched.h>
sched_yield()
这篇关于nginx自旋锁ngx_spinlock分析的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!