Linux核心同步方式剖析-(下)

來源:互聯網
上載者:User
    自旋鎖有兩種可用的形式:完全鎖(full lock)和讀寫鎖。 首先看一下完全鎖。

    首先通過一個簡單的聲明建立一個新的自旋鎖。這可以通過調用 spin_lock_init 進行初始化。清單 5 中顯示的每個變數都會實現相同的結果。

清單 5. 建立和初始化自旋鎖                spinlock_t my_spinlock = SPIN_LOCK_UNLOCKED;... or ...DEFINE_SPINLOCK( my_spinlock );... or ...spin_lock_init( &my_spinlock );

定義了自旋鎖之後,就可以使用大量的鎖定變數了。每個變數用於不同的上下文。

    清單 6 中顯示了 spin_lock 和 spin_unlock 變數。這是一個最簡單的變數,它不會執行中斷禁用,但是包含全部的記憶體壁壘(memory barrier)。這個變數假定中斷處理常式和該鎖之間沒有互動。

清單 6. 自旋鎖 lock 和 unlock 函數                                spin_lock( &my_spinlock );// critical sectionspin_unlock( &my_spinlock );

    接下來是 irqsave 和 irqrestore 對,如清單 7 所示。spin_lock_irqsave 函數需要自旋鎖,並且在本地處理器(在 SMP 情形中)上禁用中斷。spin_unlock_irqrestore 函數釋放自旋鎖,並且(通過 flags 參數)恢複中斷。

清單 7. 自旋鎖變數,其中禁用了本地 CPU 中斷                                spin_lock_irqsave( &my_spinlock, flags );// critical sectionspin_unlock_irqrestore( &my_spinlock, flags );

spin_lock_irqsave/spin_unlock_irqrestore 的一個不太安全的變體是 spin_lock_irq/spin_unlock_irq。 我建議不要使用此變體,因為它會假設中斷狀態。

    最後,如果核心線程通過 bottom half 方式共用資料,那麼可以使用自旋鎖的另一個變體。bottom half 方法可以將裝置驅動程式中的工作延遲到中斷處理後執行。這種自旋鎖禁用了本地 CPU 上的非強制中斷。這可以阻止 softirq、tasklet 和 bottom half 在本地 CPU 上運行。這個變體如清單 8 所示。

清單 8. 自旋鎖函數實現 bottom-half 互動                                spin_lock_bh( &my_spinlock );// critical sectionspin_unlock_bh( &my_spinlock );

讀/寫鎖

    在許多情形下,對資料的訪問是由大量的讀和少量的寫操作來完成的(讀取資料比寫入資料更常見)。讀/寫鎖的建立就是為了支援這種模型。這個模型有趣的地方在於允許多個線程同時訪問相同資料,但同一時刻只允許一個線程寫入資料。如果執行寫操作的線程持有此鎖,則臨界段不能由其他線程讀取。如果一個執行讀操作的線程持有此鎖,那麼多個讀線程都可以進入臨界段。清單 9 示範了這個模型。

清單 9. 讀/寫自旋鎖函數                rwlock_t my_rwlock;rwlock_init( &my_rwlock );write_lock( &my_rwlock );// critical section -- can read and writewrite_unlock( &my_rwlock );read_lock( &my_rwlock );// critical section -- can read onlyread_unlock( &my_rwlock );

    根據對鎖的需求,還針對 bottom half 和插斷要求(IRQ)對讀/寫自旋鎖進行了修改。顯然,如果您使用的是原版的讀/寫鎖,那麼按照標準自旋鎖的用法使用這個自旋鎖,而不區分讀線程和寫線程。

核心互斥鎖

    在核心中可以使用互斥鎖來實現訊號量行為。核心互斥鎖是在原子 API 之上實現的,但這對於核心使用者是不可見的。互斥鎖很簡單,但是有一些規則必須牢記。同一時間只能有一個任務持有互斥鎖,而且只有這個任務可以對互斥鎖進行解鎖。互斥鎖不能進行遞迴鎖定或解鎖,並且互斥鎖可能不能用於互動上下文。但是互斥鎖比當前的核心訊號量選項更快,並且更加緊湊,因此如果它們滿足您的需求,那麼它們將是您明智的選擇。

    可以通過 DEFINE_MUTEX 宏使用一個操作建立和初始化互斥鎖。這將建立一個新的互斥鎖並初始化其結構。可以在 ./linux/include/linux/mutex.h 中查看該實現。

    互斥鎖 API 提供了 5 個函數:其中 3 個用於鎖定,一個用於解鎖,另一個用於測試互斥鎖。首先看一下鎖定函數。在需要立即鎖定以及希望在互斥鎖不可用時掌握控制的情形下,可以使用第一個函數 mutex_trylock。該函數如清單 10 所示。

清單 10. 嘗試使用 mutex_trylock 獲得互斥鎖                 ret = mutex_trylock( &my_mutex );if (ret != 0) {  // Got the lock!} else {  // Did not get the lock}

    如果想等待這個鎖,可以調用 mutex_lock。這個調用在互斥鎖可用時返回,否則,在互斥鎖鎖可用之前它將休眠。無論在哪種情形中,當控制被返回時,調用者將持有互斥鎖。最後,當調用者休眠時使用 mutex_lock_interruptible。在這種情況下,該函數可能返回 -EINTR。清單 11 中顯示了這兩種調用。

清單 11. 鎖定一個可能處於休眠狀態的互斥鎖                                mutex_lock( &my_mutex );// Lock is now held by the caller.if (mutex_lock_interruptible( &my_mutex ) != 0)  {  // Interrupted by a signal, no mutex held}

    當一個互斥鎖被鎖定後,它必須被解鎖。這是由 mutex_unlock 函數來完成的。這個函數不能從中斷上下文調用。最後,可以通過調用 mutex_is_locked 檢查互斥鎖的狀態。這個調用實際上編譯成一個內嵌函式。如果互斥鎖被持有(鎖定),那麼就會返回 1;否則,返回 0。清單 12 示範了這些函數。

清單 12. 用 mutex_is_locked 測試互斥鎖鎖                                 mutex_unlock( &my_mutex );if (mutex_is_locked( &my_mutex ) == 0) {  // Mutex is unlocked}

    互斥鎖 API 存在著自身的局限性,因為它是基於原子 API 的。但是其效率比較高,如果能滿足你的需要,還是可以使用的。

大核心鎖(Big kernel lock)

     最後看一下大核心鎖(BLK)。它在核心中的用途越來越小,但是仍然有一些保留下來的用法。BKL 使多處理器 Linux 成為可能,但是細粒度(finer-grained)鎖正在慢慢取代 BKL。BKL 通過 lock_kernel 和 unlock_kernel 函數提供。要獲得更多資訊,請查看 ./linux/lib/kernel_lock.c。

 

Linux 效能非凡,其鎖定方法也一樣。原子鎖不僅提供了一種鎖定機制,同時也提供了算術或 bitwise 操作。自旋鎖提供了一種鎖定機制(主要應用於 SMP),而且讀/寫自旋鎖允許多個讀線程且僅有一個寫線程獲得給定的鎖。最後,互斥鎖是一種新的鎖定機制,提供了一種構建在原子之上的簡單 API。不管你需要什麼,Linux 都會提供一種鎖定方案保護您的資料。

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.