diff options
Diffstat (limited to '')
-rw-r--r-- | Documentation/translations/zh_TW/process/4.Coding.rst | 104 |
1 files changed, 52 insertions, 52 deletions
diff --git a/Documentation/translations/zh_TW/process/4.Coding.rst b/Documentation/translations/zh_TW/process/4.Coding.rst index adb5339aab..7a4e01eabd 100644 --- a/Documentation/translations/zh_TW/process/4.Coding.rst +++ b/Documentation/translations/zh_TW/process/4.Coding.rst @@ -19,7 +19,7 @@ ====================== 雖然一個堅實的、面向社區的設計過程有很多值得說道的,但是任何內核開發項目工作 -的證明都反映在代碼中。它是將由其他開發人員檢查併合並(或不合併)到主線樹中 +的證明都反映在代碼中。它是將由其他開發人員檢查併合並(或不合並)到主線樹中 的代碼。所以這段代碼的質量決定了項目的最終成功。 本節將檢查編碼過程。我們將從內核開發人員常犯的幾種錯誤開始。然後重點將轉移 @@ -32,7 +32,7 @@ ******** 內核長期以來都有其標準的代碼風格,如 -:ref:`Documentation/translations/zh_TW/process/coding-style.rst <tw_codingstyle>` +:ref:`Documentation/translations/zh_CN/process/coding-style.rst <tw_codingstyle>` 中所述。在多數時候,該文檔中描述的準則至多被認爲是建議性的。因此,內核中存在 大量不符合代碼風格準則的代碼。這種代碼的存在會給內核開發人員帶來兩方面的危害。 @@ -42,7 +42,7 @@ 開發人員能夠快速理解其中的任何部分。所以再也經不起奇怪格式的代碼的折騰了。 內核的代碼風格偶爾會與僱主的強制風格發生衝突。在這種情況下,必須在代碼合併 -之前遵從內核代碼風格。將代碼放入內核意味著以多種方式放棄一定程度的控制權—— +之前遵從內核代碼風格。將代碼放入內核意味着以多種方式放棄一定程度的控制權—— 包括控制代碼樣式。 另一個危害是認爲已經在內核中的代碼迫切需要修復代碼樣式。開發者可能會開始編寫 @@ -70,21 +70,21 @@ 簡單點,先考慮一個調用時始終只有一個參數且總爲零的函數。我們可以保留這個參數, 以在需要使用它時提供的額外靈活性。不過,在那時實現了這個額外參數的代碼很有 可能以某種從未被注意到的微妙方式被破壞——因爲它從未被使用過。或者當需要額外 -的靈活性時,它並未以符合程式設計師當初期望的方式來實現。內核開發人員通常會提交 +的靈活性時,它並未以符合程序員當初期望的方式來實現。內核開發人員通常會提交 補丁來刪除未使用的參數;一般來說,一開始就不應該添加這些參數。 -隱藏硬體訪問的抽象層——通常爲了允許大量的驅動程序兼容多個作業系統——尤其不受 +隱藏硬件訪問的抽象層——通常爲了允許大量的驅動程序兼容多個操作系統——尤其不受 歡迎。這樣的層使代碼變得模糊,可能會造成性能損失;它們不屬於Linux內核。 另一方面,如果您發現自己從另一個內核子系統複製了大量的代碼,那麼是時候 -了解一下:是否需要將這些代碼中的部分提取到單獨的庫中,或者在更高的層次上 +瞭解一下:是否需要將這些代碼中的部分提取到單獨的庫中,或者在更高的層次上 實現這些功能。在整個內核中複製相同的代碼沒有價值。 #ifdef 和預處理 *************** -C預處理器似乎給一些C程式設計師帶來了強大的誘惑,他們認爲它是一種將大量靈活性加入 -原始碼中的方法。但是預處理器不是C,大量使用它會導致代碼對其他人來說更難閱讀, +C預處理器似乎給一些C程序員帶來了強大的誘惑,他們認爲它是一種將大量靈活性加入 +源代碼中的方法。但是預處理器不是C,大量使用它會導致代碼對其他人來說更難閱讀, 對編譯器來說更難檢查正確性。使用了大量預處理器幾乎總是代碼需要一些 清理工作的標誌。 @@ -100,23 +100,23 @@ C預處理器宏存在許多危險性,包括可能對具有副作用且沒有 內聯函數 ******** -不過,內聯函數本身也存在風險。程式設計師可以傾心於避免函數調用和用內聯函數填充源 +不過,內聯函數本身也存在風險。程序員可以傾心於避免函數調用和用內聯函數填充源 文件所固有的效率。然而,這些功能實際上會降低性能。因爲它們的代碼在每個調用站 -點都被複製一遍,所以最終會增加編譯內核的大小。此外,這也對處理器的內存緩存 +點都被複制一遍,所以最終會增加編譯內核的大小。此外,這也對處理器的內存緩存 造成壓力,從而大大降低執行速度。通常內聯函數應該非常小,而且相對較少。畢竟 函數調用的成本並不高;大量創建內聯函數是過早優化的典型例子。 -一般來說,內核程式設計師會自冒風險忽略緩存效果。在數據結構課程開頭中的經典 -時間/空間權衡通常不適用於當代硬體。空間 *就是* 時間,因爲一個大的程序比一個 +一般來說,內核程序員會自冒風險忽略緩存效果。在數據結構課程開頭中的經典 +時間/空間權衡通常不適用於當代硬件。空間 *就是* 時間,因爲一個大的程序比一個 更緊湊的程序運行得慢。 較新的編譯器越來越激進地決定一個給定函數是否應該內聯。因此,隨意放置使用 -「inline」關鍵字可能不僅僅是過度的,也可能是無用的。 +“inline”關鍵字可能不僅僅是過度的,也可能是無用的。 鎖 ** -2006年5月,「deviceescape」網絡堆棧在前呼後擁下以GPL發布,並被納入主線內核。 +2006年5月,“deviceescape”網絡堆棧在前呼後擁下以GPL發佈,並被納入主線內核。 這是一個受歡迎的消息;Linux中對無線網絡的支持充其量被認爲是不合格的,而 Deviceescape堆棧承諾修復這種情況。然而直到2007年6月(2.6.22),這段代碼才真 正進入主線。發生了什麼? @@ -125,25 +125,25 @@ Deviceescape堆棧承諾修復這種情況。然而直到2007年6月(2.6.22) 設計。在合併這個網絡堆棧(現在稱爲mac80211)之前,需要對其進行一個鎖方案的 改造。 -曾經,Linux內核代碼可以在不考慮多處理器系統所帶來的並發性問題的情況下進行 +曾經,Linux內核代碼可以在不考慮多處理器系統所帶來的併發性問題的情況下進行 開發。然而現在,這個文檔就是在雙核筆記本電腦上寫的。即使在單處理器系統上, -爲提高響應能力所做的工作也會提高內核內的並發性水平。編寫內核代碼而不考慮鎖 +爲提高響應能力所做的工作也會提高內核內的併發性水平。編寫內核代碼而不考慮鎖 的日子早已遠去。 -可以由多個線程並發訪問的任何資源(數據結構、硬體寄存器等)必須由鎖保護。新 +可以由多個線程併發訪問的任何資源(數據結構、硬件寄存器等)必須由鎖保護。新 的代碼應該謹記這一要求;事後修改鎖是一項相當困難的任務。內核開發人員應該花 -時間充分了解可用的鎖原語,以便爲工作選擇正確的工具。對並發性缺乏關注的代碼 +時間充分了解可用的鎖原語,以便爲工作選擇正確的工具。對併發性缺乏關注的代碼 很難進入主線。 -回歸 +迴歸 **** -最後一個值得一提的危險是回歸:它可能會引起導致現有用戶的某些東西中斷的改變 -(這也可能會帶來很大的改進)。這種變化被稱爲「回歸」,回歸已經成爲主線內核 -最不受歡迎的問題。除了少數例外情況,如果回歸不能及時修正,會導致回歸的修改 -將被取消。最好首先避免回歸發生。 +最後一個值得一提的危險是迴歸:它可能會引起導致現有用戶的某些東西中斷的改變 +(這也可能會帶來很大的改進)。這種變化被稱爲“迴歸”,迴歸已經成爲主線內核 +最不受歡迎的問題。除了少數例外情況,如果迴歸不能及時修正,會導致迴歸的修改 +將被取消。最好首先避免迴歸發生。 -人們常常爭論,如果回歸帶來的功能遠超過產生的問題,那麼回歸是否爲可接受的。 +人們常常爭論,如果迴歸帶來的功能遠超過產生的問題,那麼迴歸是否爲可接受的。 如果它破壞了一個系統卻爲十個系統帶來新的功能,爲何不改改態度呢?2007年7月, Linus對這個問題給出了最佳答案: @@ -154,7 +154,7 @@ Linus對這個問題給出了最佳答案: (http://lwn.net/Articles/243460/) -特別不受歡迎的一種回歸類型是用戶空間ABI的任何變化。一旦接口被導出到用戶空間, +特別不受歡迎的一種迴歸類型是用戶空間ABI的任何變化。一旦接口被導出到用戶空間, 就必須無限期地支持它。這一事實使得用戶空間接口的創建特別具有挑戰性:因爲它們 不能以不兼容的方式進行更改,所以必須一次就對。因此,用戶空間接口總是需要大量 的思考、清晰的文檔和廣泛的審查。 @@ -171,19 +171,19 @@ Linus對這個問題給出了最佳答案: 第一步是注意編譯器產生的警告。當前版本的GCC可以檢測(並警告)大量潛在錯誤。 通常,這些警告都指向真正的問題。提交以供審閱的代碼一般不會產生任何編譯器警告。 -在消除警告時,注意了解真正的原因,並儘量避免僅「修復」使警告消失而不解決其原因。 +在消除警告時,注意瞭解真正的原因,並儘量避免僅“修復”使警告消失而不解決其原因。 -請注意,並非所有編譯器警告都默認啓用。使用「make KCFLAGS=-W」構建內核以 +請注意,並非所有編譯器警告都默認啓用。使用“make KCFLAGS=-W”構建內核以 獲得完整集合。 -內核提供了幾個配置選項,可以打開調試功能;大多數配置選項位於「kernel hacking」 +內核提供了幾個配置選項,可以打開調試功能;大多數配置選項位於“kernel hacking” 子菜單中。對於任何用於開發或測試目的的內核,都應該啓用其中幾個選項。特別是, 您應該打開: - FRAME_WARN 獲取大於給定數量的堆棧幀的警告。 這些警告生成的輸出可能比較冗長,但您不必擔心來自內核其他部分的警告。 - - DEBUG_OBJECTS 將添加代碼以跟蹤內核創建的各種對象的生命周期,並在出現問題 + - DEBUG_OBJECTS 將添加代碼以跟蹤內核創建的各種對象的生命週期,並在出現問題 時發出警告。如果你要添加創建(和導出)關於其自己的複雜對象的子系統,請 考慮打開對象調試基礎結構的支持。 @@ -195,34 +195,34 @@ Linus對這個問題給出了最佳答案: 還有很多其他調試選項,其中一些將在下面討論。其中一些有顯著的性能影響,不應 一直使用。在學習可用選項上花費一些時間,可能會在短期內得到許多回報。 -其中一個較重的調試工具是鎖檢查器或「lockdep」。該工具將跟蹤系統中每個鎖 +其中一個較重的調試工具是鎖檢查器或“lockdep”。該工具將跟蹤系統中每個鎖 (spinlock或mutex)的獲取和釋放、獲取鎖的相對順序、當前中斷環境等等。然後, 它可以確保總是以相同的順序獲取鎖,相同的中斷假設適用於所有情況等等。換句話 說,lockdep可以找到許多導致系統死鎖的場景。在部署的系統中,這種問題可能會 很痛苦(對於開發人員和用戶而言);LockDep允許提前以自動方式發現問題。具有 -任何類型的非普通鎖的代碼在提交合併前應在啓用lockdep的情況下運行測試。 +任何類型的非普通鎖的代碼在提交合並前應在啓用lockdep的情況下運行測試。 -作爲一個勤奮的內核程式設計師,毫無疑問,您將檢查任何可能失敗的操作(如內存分配) +作爲一個勤奮的內核程序員,毫無疑問,您將檢查任何可能失敗的操作(如內存分配) 的返回狀態。然而,事實上,最終的故障復現路徑可能完全沒有經過測試。未測試的 代碼往往會出問題;如果所有這些錯誤處理路徑都被執行了幾次,那麼您可能對代碼 更有信心。 內核提供了一個可以做到這一點的錯誤注入框架,特別是在涉及內存分配的情況下。 啓用故障注入後,內存分配的可配置失敗的百分比;這些失敗可以限定在特定的代碼 -範圍內。在啓用了故障注入的情況下運行,程式設計師可以看到當情況惡化時代碼如何響 +範圍內。在啓用了故障注入的情況下運行,程序員可以看到當情況惡化時代碼如何響 應。有關如何使用此工具的詳細信息,請參閱 Documentation/fault-injection/fault-injection.rst。 -「sparse」靜態分析工具可以發現其他類型的錯誤。sparse可以警告程式設計師用戶空間 +“sparse”靜態分析工具可以發現其他類型的錯誤。sparse可以警告程序員用戶空間 和內核空間地址之間的混淆、大端序與小端序的混淆、在需要一組位標誌的地方傳遞 -整數值等等。sparse必須單獨安裝(如果您的分發伺服器沒有將其打包, +整數值等等。sparse必須單獨安裝(如果您的分發服務器沒有將其打包, 可以在 https://sparse.wiki.kernel.org/index.php/Main_page 找到), -然後可以通過在make命令中添加「C=1」在代碼上運行它。 +然後可以通過在make命令中添加“C=1”在代碼上運行它。 -「Coccinelle」工具 :ref:`http://coccinelle.lip6.fr/ <devtools_coccinelle>` -能夠發現各種潛在的編碼問題;它還可以爲這些問題提出修複方案。在 -scripts/coccinelle目錄下已經打包了相當多的內核「語義補丁」;運行 -「make coccicheck」將運行這些語義補丁並報告發現的任何問題。有關詳細信息,請參閱 +“Coccinelle”工具 :ref:`http://coccinelle.lip6.fr/ <devtools_coccinelle>` +能夠發現各種潛在的編碼問題;它還可以爲這些問題提出修復方案。在 +scripts/coccinelle目錄下已經打包了相當多的內核“語義補丁”;運行 +“make coccicheck”將運行這些語義補丁並報告發現的任何問題。有關詳細信息,請參閱 :ref:`Documentation/dev-tools/coccinelle.rst <devtools_coccinelle>` @@ -247,7 +247,7 @@ scripts/coccinelle目錄下已經打包了相當多的內核「語義補丁」 任何添加新用戶空間接口的代碼——包括新的sysfs或/proc文件——都應該包含該接口 的文檔,該文檔使用戶空間開發人員能夠知道他們在使用什麼。請參閱 -Documentation/ABI/README,了解如何此文檔格式以及需要提供哪些信息。 +Documentation/ABI/README,瞭解如何此文檔格式以及需要提供哪些信息。 文檔 :ref:`Documentation/admin-guide/kernel-parameters.rst <kernelparameters>` 描述了內核的所有引導時間參數。任何添加新參數的補丁都應該向該文檔添加適當的 @@ -256,27 +256,27 @@ Documentation/ABI/README,了解如何此文檔格式以及需要提供哪些 任何新的配置選項都必須附有幫助文本,幫助文本需清楚地解釋這些選項以及用戶可能 希望何時使用它們。 -許多子系統的內部API信息通過專門格式化的注釋進行記錄;這些注釋可以通過 -「kernel-doc」腳本以多種方式提取和格式化。如果您在具有kerneldoc注釋的子系統中 +許多子系統的內部API信息通過專門格式化的註釋進行記錄;這些註釋可以通過 +“kernel-doc”腳本以多種方式提取和格式化。如果您在具有kerneldoc註釋的子系統中 工作,則應該維護它們,並根據需要爲外部可用的功能添加它們。即使在沒有如此記錄 -的領域中,爲將來添加kerneldoc注釋也沒有壞處;實際上,這對於剛開始開發內核的人 -來說是一個有用的活動。這些注釋的格式以及如何創建kerneldoc模板的一些信息可以在 +的領域中,爲將來添加kerneldoc註釋也沒有壞處;實際上,這對於剛開始開發內核的人 +來說是一個有用的活動。這些註釋的格式以及如何創建kerneldoc模板的一些信息可以在 :ref:`Documentation/doc-guide/ <doc_guide>` 上找到。 -任何閱讀大量現有內核代碼的人都會注意到,注釋的缺失往往是最值得注意的。同時, -對新代碼的要求比過去更高;合併未注釋的代碼將更加困難。這就是說,人們並不期望 -詳細注釋的代碼。代碼本身應該是自解釋的,注釋闡釋了更微妙的方面。 +任何閱讀大量現有內核代碼的人都會注意到,註釋的缺失往往是最值得注意的。同時, +對新代碼的要求比過去更高;合併未註釋的代碼將更加困難。這就是說,人們並不期望 +詳細註釋的代碼。代碼本身應該是自解釋的,註釋闡釋了更微妙的方面。 -某些事情應該總是被注釋。使用內存屏障時,應附上一行文字,解釋爲什麼需要設置內存 +某些事情應該總是被註釋。使用內存屏障時,應附上一行文字,解釋爲什麼需要設置內存 屏障。數據結構的鎖規則通常需要在某個地方解釋。一般來說,主要數據結構需要全面 的文檔。應該指出代碼中分立的位之間不明顯的依賴性。任何可能誘使代碼管理人進行 -錯誤的「清理」的事情都需要一個注釋來說明爲什麼要這樣做。等等。 +錯誤的“清理”的事情都需要一個註釋來說明爲什麼要這樣做。等等。 內部API更改 ----------- -內核提供給用戶空間的二進位接口不能被破壞,除非逼不得已。而內核的內部編程接口 +內核提供給用戶空間的二進制接口不能被破壞,除非逼不得已。而內核的內部編程接口 是高度流動的,當需要時可以更改。如果你發現自己不得不處理一個內核API,或者僅 僅因爲它不滿足你的需求導致無法使用特定的功能,這可能是API需要改變的一個標誌。 作爲內核開發人員,您有權進行此類更改。 @@ -287,7 +287,7 @@ Documentation/ABI/README,了解如何此文檔格式以及需要提供哪些 另一個要點是,更改內部API的開發人員通常要負責修復內核樹中被更改破壞的任何代碼。 對於一個廣泛使用的函數,這個責任可以導致成百上千的變化,其中許多變化可能與其他 -開發人員正在做的工作相衝突。不用說,這可能是一項大工程,所以最好確保理由是 +開發人員正在做的工作相沖突。不用說,這可能是一項大工程,所以最好確保理由是 可靠的。請注意,coccinelle工具可以幫助進行廣泛的API更改。 在進行不兼容的API更改時,應儘可能確保編譯器捕獲未更新的代碼。這將幫助您確保找 |