5.2. 并發(fā)和它的管理

2018-02-24 15:49 更新

5.2.?并發(fā)和它的管理

在現(xiàn)代 Linux 系統(tǒng), 有非常多的并發(fā)源, 并且因此而來的可能競爭情況. 多個用戶空間進程在運行, 它們可能以令人驚訝的方式組合存取你的代碼. SMP 系統(tǒng)能夠同時在不同處理器上執(zhí)行你的代碼. 內(nèi)核代碼是可搶占的; 你的驅(qū)動代碼可能在任何時間失去處理器, 代替它的進程可能也在你的驅(qū)動中運行. 設(shè)備中斷是能夠?qū)е履愕拇a并發(fā)執(zhí)行的異步事件. 內(nèi)核也提供各種延遲代碼執(zhí)行的機制, 例如 workqueue, tasklet, 以及定時器, 這些能夠使你的代碼在任何時間以一種與當前進程在做的事情無關(guān)的方式運行. 在現(xiàn)代的, 熱插拔的世界中, 你的設(shè)備可能在你使用它們的時候輕易地消失.

避免競爭情況可能是一個令人害怕的工作. 在一個任何時候可能發(fā)生任何事的世界, 驅(qū)動程序員如何避免產(chǎn)生絕對的混亂? 事實證明, 大部分競爭情況可以避免, 通過一些想法, 內(nèi)核并發(fā)控制原語, 以及幾個基本原則的應(yīng)用. 我們會先從原則開始, 接著進入如何使用它們的細節(jié)中

競爭情況來自對資源的共享存取的結(jié)果. 當 2 個執(zhí)行的線路[17]有機會操作同一個數(shù)據(jù)結(jié)構(gòu)(或者硬件資源), 混合的可能性就一直存在. 因此第一個經(jīng)驗法則是在你設(shè)計驅(qū)動時在任何可能的時候記住避免共享的資源. 如果沒有并發(fā)存取, 就沒有競爭情況. 因此小心編寫的內(nèi)核代碼應(yīng)當有最小的共享. 這個想法的最明顯應(yīng)用是避免使用全局變量. 如果你將一個資源放在多個執(zhí)行線路能夠找到它的地方, 應(yīng)當有一個很強的理由這樣做.

事實是, 然而, 這樣的共享常常是需要的. 硬件資源是, 由于它們的特性, 共享的, 軟件資源也必須常常共享給多個線程. 也要記住全局變量遠遠不是共享數(shù)據(jù)的唯一方式; 任何時候你的代碼傳遞一個指針給內(nèi)核的其他部分, 潛在地它創(chuàng)造了一個新的共享情形. 共享是生活的事實.

這是資源共享的硬規(guī)則: 任何時候一個硬件或軟件資源被超出一個單個執(zhí)行線程共享, 并且可能存在一個線程看到那個資源的不一致時, 你必須明確地管理對那個資源的存取. 在上面的 scull 例子, 這個情況在進程 B 看來是不一致的; 不知道進程 A 已經(jīng)為( 共享的 ) 設(shè)備分配了內(nèi)存, 它做它自己的分配并且覆蓋了 A 的工作. 在這個例子里, 我們必須控制對 scull 數(shù)據(jù)結(jié)構(gòu)的存取. 我們需要安排, 這樣代碼或者看到內(nèi)存已經(jīng)分配了, 或者知道沒有內(nèi)存已經(jīng)或者將要被其他人分配. 存取管理的常用技術(shù)是加鎖或者互斥 -- 確保在任何時間只有一個執(zhí)行線程可以操作一個共享資源. 本章剩下的大部分將專門介紹加鎖.

然而, 首先, 我們必須簡短考慮一下另一個重要規(guī)則. 當內(nèi)核代碼創(chuàng)建一個會被內(nèi)核其他部分共享的對象時, 這個對象必須一直存在(并且功能正常)到它知道沒有對它的外部引用存在為止. scull 使它的設(shè)備可用的瞬間, 它必須準備好處理對那些設(shè)備的請求. 并且 scull 必須一直能夠處理對它的設(shè)備的請求直到它知道沒有對這些設(shè)備的引用(例如打開的用戶空間文件)存在. 2 個要求出自這個規(guī)則: 除非它處于可以正確工作的狀態(tài), 不能有對象能對內(nèi)核可用, 對這樣的對象的引用必須被跟蹤. 在大部分情況下, 你將發(fā)現(xiàn)內(nèi)核為你處理引用計數(shù), 但是常常有例外.

遵照上面的規(guī)則需要計劃和對細節(jié)小心注意. 容易被對資源的并發(fā)存取而吃驚, 你事先并沒有認識到被共享. 通過一些努力, 然而, 大部分競爭情況能夠在它們咬到你或者你的用戶前被消滅.

[17] 本章的意圖, 一個執(zhí)行"線程"是任何運行代碼的上下文. 每個進程顯然是一個執(zhí)行線程, 但是一個中斷處理也是, 或者其他響應(yīng)一個異步內(nèi)核事件的代碼.

以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號