linux原子锁原理,了解Linux的锁与同步、原子加(atomic_add)
了解Linux的鎖與同步、原子加(atomic_add)
因為需要效率更高的互斥,linux中的atomic_add()可以實現這個需求。沒有接觸過內核,現在貼一些相關內容,有空看下。
了解Linux的鎖與同步
上周看了Linux的進程與線程,對操作系統的底層有了更進一步的一些了解。我同時用Linux內核設計與實現和Solaris內核結構兩本書對比著看,這樣更容易產生對比和引發思考。現代操作系統很多思路都是相同的,比如搶占式的多線程及內核、虛擬內存管理等方面。但另外一方面還是有很多差異。在了解鎖和同步之前,原子操作是所有一切底層實現的基礎。
原子操作Atomic
通常操作系統和硬件都提供特性,可以對一個字節進行原子操作的的讀寫,并且通常在此基礎上來實現更高級的鎖特性。
atomic_t結構
原子操作通常針對int或bit類型的數據,但是Linux并不能直接對int進行原子操作,而只能通過atomic_t的數據結構來進行。目前了解到的原因有兩個。
一是在老的Linux版本,atomic_t實際只有24位長,低8位用來做鎖,如下圖所示。這是由于Linux是一個跨平臺的實現,可以運行在多種 CPU上,有些類型的CPU比如SPARC并沒有原生的atomic指令支持,所以只能在32位int使用8位來做同步鎖,避免多個線程同時訪問。(最新版SPARC實現已經突破此限制)
另外一個原因是避免atomic_t傳遞到程序其他地方進行操作修改等。強制使用atomic_t,則避免被不恰當的誤用。
atomic_t my_counter = ATOMIC_INIT(0);
val = atomic_read( &my_counter );
atomic_add( 1, &my_counter );
atomic_inc( &my_counter );
atomic_sub( 1, &my_counter );
atomic_dec( &my_counter );
原子操作硬件上的實現
Solaris的實現是基于test-and-set的指令,并且該指令為原子操作。比如Solaris的實現在SPARC上是基于ldstub和cas指令,在x86上用的是cmpxchg指令。但是Linux似乎直接用的add指令。
OpenSolaris i386的實現
movl 4(%esp), %edx / %edx = target address
movl (%edx), %eax / %eax = old value1: leal 1(%eax), %ecx /
%ecx = new value lock cmpxchgl %ecx, (%edx) / try to stick it in jne 1b movl %ecx, %eax /
return new value ret
在Linux源代碼asm_i386/atomic.h中
/** * atomic_add - add integer to atomic variable
*@i: integer value to add
*@v: pointer of type atomic_t
*Atomically adds @i to @v.
Note that the guaranteed useful range * of an atomic_t is only 24 bits.
*/
static __inline__ void atomic_add(int i, atomic_t *v){
__asm__ __volatile__( LOCK "addl %1,%0" :"=m" (v->counter) :"ir" (i), "m" (v->counter));}
鎖的類型
Spinlocks自旋鎖
如果鎖被占用,嘗試獲取鎖的線程進入busy-wait狀態,即CPU不停的循環檢查鎖是否可用。自旋鎖適合占用鎖非常短的場合,避免等待鎖的線程sleep而帶來的CPU兩個context switch的開銷。
Semaphores信號量
如果鎖被占用,嘗試獲取鎖的線程進入sleep狀態,CPU切換到別的線程。當鎖釋放之后,系統會自動喚醒sleep的線程。信號量適合對鎖占用較長時間的場合。
Adaptive locks自適應鎖
顧名思義,自適應鎖就是上面兩種的結合。當線程嘗試申請鎖,會自動根據擁有鎖的線程繁忙或sleep來選擇是busy wait還是sleep。這種鎖只有Solaris內核提供,Linux上未見有相關描述。
幾種鎖的性能比較(Windows操作系統下,第一種類似atomic_inc, 2,3類似spinlock, 4,5類似semaphore)
(圖片來源:Intel Software Network)
Solaris
感覺OpenSolaris在很多地方要比Linux優秀,Solaris在理論設計和實踐上都非常優雅,而Linux內核很多地方似乎更偏工程實踐方向一些。另外Solaris用來做學習操作系統更合適,它的mdb幾乎無所不能。
我在VirtualBox虛擬機上安裝了OpenSolaris,非常容易安裝,使用這個Minimal OpenSolaris Appliance OVF image for VirtualBox 2.2?簡易方法,安裝一個沒有gui的版本,大約3分鐘以內就可以裝好。OpenSolaris安裝軟件和Ubuntu一樣方便,使用 pkg install SUNWxxx 的命令,比如 pkg install SUNWcurl
No related posts.
自旋鎖的主要用途是用于一些不能休眠的情況,比如中斷上下文中。
總結
以上是生活随笔為你收集整理的linux原子锁原理,了解Linux的锁与同步、原子加(atomic_add)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【Java】如何使用Java API?
- 下一篇: vue js 图像标注 --- canv