Background:
工作中需要避免兩個人同時在一台Linux部署測試環境,需要鎖同步。(當然還有其他方法去避免這樣的問題,比如用不同的使用權限設定)。Linux 裡面真是強大,已經提供對檔案加鎖的工具。一類是flock,另外還有一組(lockfile-create, lockfile-check, lockfile-touch, lockfile-remove)。
Question:
但是電腦裡面鎖是如何?的?需要藉助原子操作。那原子操作如何?呢?
如果是單CPU,可以用屏蔽中斷,不去調度任何其他進程線程,保證指令的原子性。那麼多CPU 又是如何保證的呢? 需要機器硬體支援。CUP提供的有原子指令,比如 Test-set,test-clear, 比如原子操作是通過DDR內部支援的,From wiki: http://en.wikipedia.org/wiki/Test-and-set
When CPU 1 issues a test-and-set instruction, the DPRAM first makes an "internal note" of this by storing the address of the memory location in a special place. If at this point, CPU 2 happens to issue a test-and-set instruction for the same memory location, the DPRAM first checks its "internal note", recognizes the situation, and issues a BUSY interrupt, which tells CPU 2 that it must wait and retry. This is an implementation of a busy waiting or spinlock using the interrupt mechanism. Since this all happens at hardware speeds, CPU 2's wait to get out of the spin-lock is very short.
Whether or not CPU 2 was trying access the memory location, the DPRAM performs the test given by CPU 1. If the test succeeds, the DPRAM sets the memory location to the value given by CPU 1. Then the DPRAM wipes out its "internal note" that CPU 1 was writing there. At this point, CPU 2 could issue a test-and-set, which would succeed.
”
當第一個CPU發出test-and-set 指令時,DPRAM 會給被訪問的記憶體做一個標記。當其他CPU也訪問該記憶體時,會檢查其標誌位。如果發現已經被設定標記位,則BUSY 中斷返回告訴其已經被其他人訪問,應該等待。 如果CPU 發現測試通過,將設定該記憶體為1,並清楚標記位。這時第二個CPU可以訪問。
鎖需要原子操作支援,原子操作需要硬體支援。可以鎖是整個系統的全域資源,是屬於核心部分。 這也可以解釋,為什麼多個CPU同時去擷取一個鎖,但是只有一個人擷取到,其他的都沒有。同樣Semaphore 也同樣可以用test-set 指令來實現,只是set變成加1,或者減1.
多線程編程裡面少不了mutex, condition and semaphore. (http://www.cnblogs.com/zhyg6516/admin/EditPosts.aspx?opt=1)
Other Reference:
1. http://embedlinux.ycool.com/post.2944092.html【如何更好理解鎖的範圍,鎖的有效性】
2. http://fxr.watson.org/fxr/source/arch/alpha/include/asm/system.h?v=linux-2.6#L359 [可以查看不同開源的作業系統的源碼,可以查看lock在linux系統如何?的]