nginx无锁机制的学习
来源:互联网 发布:如何分析竞价数据 编辑:程序博客网 时间:2024/06/05 20:55
在nginx中,广泛应用了CAS(compare-and-swap)操作来完成进程同步。
包括ngx_spinlock,ngx_trylock,ngx_rwlock_wlock,ngx_rwlock_rlock,ngx_shmtx_trylock,ngx_shmtx_lock等各种锁,均由ngx_atomic_cmp_set的CAS操作来实现。
CAS操作作为原子操作,在linux上最低的支持版本是GCC4.1,API是
__sync_bool_compare_and_swap(lock, old, set)
在windows上,相应的API是
InterlockedCompareExchange
在C++11中,进行了跨平台的扩展,STL的函数是
atomic_compare_exchange_weak(
在GCC4.1之前的版本,可以用函数来实现CAS操作,在nginx中,给出了实现,也是CAS的原理
static ngx_inline ngx_atomic_uint_tngx_atomic_cmp_set(ngx_atomic_t *lock, ngx_atomic_uint_t old, ngx_atomic_uint_t set){ if (*lock == old) { *lock = set; return 1; } return 0;}广泛应用的CAS操作,应该对应于CMPXCHG 汇编指令,是一条原子操作,更确切的实现是这样的:
static ngx_inline ngx_atomic_uint_tngx_atomic_cmp_set(ngx_atomic_t *lock, ngx_atomic_uint_t old, ngx_atomic_uint_t set){ u_char res; __asm__ volatile ( NGX_SMP_LOCK " cmpxchgq %3, %1; " " sete %0; " : "=a" (res) : "m" (*lock), "a" (old), "r" (set) : "cc", "memory"); return res;}
既然nginx中CAS是可以替代各种锁,那用CAS操作当然可以替代最简单的mutex的互斥锁。
替代的方法如下:
int mutex = 0;int lock = 0;int unlock = 1; while (!(__sync_bool_compare_and_swap (&mutex,lock, 1) ))usleep(10000);//100000 //pthread_mutex_lock(&mutex_lock); count++; // pthread_mutex_unlock(&mutex_lock); __sync_bool_compare_and_swap (&mutex, unlock, 0);
用mutex=0表示无线程用count,用mutex=1来表示有人用count。
其中usleep(10000)是我随便写的一个数,来给CPU空闲的事情,在nginx中,用ngx_cpu_pause来给cpu的空闲。
其中ngx_cpu_pause的实现为
__asm__ ("pause")
这里经测试,CAS操作的性能比mutex提升的超过10倍,而cpu的使用率基本一致,这应该是nginx高效的原因。
在nginx中,也并非完全不用mutex,仍然有用ngx_thread_mutex_lock的地方,而ngx_thread_mutex_lock的实现是mutex。
用mutex的原因,在于,需要配合条件变量来一起使用,配合ngx_thread_cond_signal,来完成线程和线程之间的任务分发。
使用mutex获取锁分为两阶段,第一阶段在用户态采用spinlock锁总线的方式获取一次锁,如果成功立即返回;否则进入第二阶段,调用系统的futex锁去sleep,当锁可用后被唤醒,继续竞争锁。这样mutex是有进入内核态,线程进行睡眠。
总结一下,mutex加cond的使用场景,是不常进入,有长期等待的环境,长时间保持锁才需要使用,比如任务的开始或结束。
线程频繁切换的地方,可以完全用CAS操作来进行了,当然采用CAS并不是最优的方法,还需要封装一个spinlock才是正经的道理。
- nginx无锁机制的学习
- 一种无锁的并发读写机制
- 无锁机制的循环缓冲技术
- nginx的rewrite机制
- Nginx的变量机制
- nginx的重试机制
- Nginx的事件处理机制
- Nginx的事件处理机制
- Nginx的事件处理机制
- Nginx定时器机制的实现
- nginx的请求处理机制
- Nginx 的事件处理机制
- Nginx服务器的缓存机制
- 19.Nginx 的缓存机制
- Windows的注册表机制,linux的无注册表机制
- Nginx的学习资料
- nginx的学习笔记
- Nginx的学习
- javascript jquery ajax 异步同步设置
- 如何构建优秀的命令行用户界面的 Python 库
- 前端面试题10
- js比较两个日期大小的简单方法
- hadoop spark hbase 单机安装
- nginx无锁机制的学习
- Java poi+excel导入
- Android开发之漫漫长途 Ⅲ——Activity的显示之Window和View(2)
- wincc 7.0往SQL Server写数据心得
- Linux网卡配置
- 【Java作业】Week06
- CAS实现SSO单点登录原理
- 树莓派 开启 ssh
- shell sort