nginx內部鎖的實現
多進程或者多線程的程序,涉及到對共享資源的修改,都需要使用到鎖。最常見的情況(也一般是然並卵的情況)是對一個全局變量進行++操作,比如有個全局變量i
,如果多個線程同時執行i++
,教科書已經提到,是會出問題的。因為i++
並不是一個原子操作,匯編之後會是三個操作:
movl i(%rip), %eax
addl $1, %eax
movl %eax, i(%rip)
這時候就需要鎖了(當然,這裏的情況,你也可以嵌入匯編的方式使用fetch-and-add的方式來避免使用鎖,不過,在多核情況下,你仍然需要加上lock前綴)。Nginx 是一個多進程的服務,並且引入了線程池,不可避免也需要用到鎖。
Nginx內部鎖的種類
讀寫鎖
相關的代碼在src/core/ngx_rwlock.[hc]
。
自旋鎖
相關的代碼在src/core/ngx_spinlock.c
。
基於共享內存的互斥鎖
相關的代碼在src/core/ngx_shmtx.[hc]
。之所以需要這個,是因為Nginx中存在多個進程,在某些操作時,比如對監聽的fd執行accept()
操作,需要互斥進行。而由於跨了多個進程,隻能將用於實現lock的內存放在共享內存。
鎖的實現
看下ngx_spinlock()
和ngx_shmtx_lock()
的代碼,會發現都使用了ngx_atomic_cmp_set()
這個函數。
未完待續。。
最後更新:2017-04-01 13:37:10