能敘述下面向對象思想在Linux內核編程中的應用嗎?

如果可以的話,請用具體的例子說明。感謝大家。


linux內核主要是C的代碼,我就簡單地從OOP三大特性——封裝、繼承和多態說說這裡的實現吧

1.首先是封裝,這個沒辦法,語言本身不支持(static能做到基於編譯單元的封裝,但還是太弱了),只能「建議」開發者不直接使用結構體內的成員(類似a-&>b),而是用介面函數調用代替(類似(getb(a))。

對於動態載入的內核模塊,內核中定義了EXPORT_SYMBOL宏,選擇性地導出了部分全局變數與介面,也就相當於封裝了其他的部分。

2.接著是繼承,以內核套接字體系為例:

struct sock {

......

}; //這可以看做套接字基類,定義了一堆通用的flag、讀寫緩存等等

之後,有inet協議族套接字

struct inet_sock {

struct sock sk;

......

}; //將sock結構作為第一個成員,即視其為基類(參考C++對象模型)

再後面,就是具體的協議套接字

struct udp_sock {

struct inet_sock inet;

......

}; //同上,視為「繼承」了inet_sock

TCP套接字多了層inet_connection_sock的繼承,在此就不贅述了。

基於此繼承體系,對於一些接受 struct sock* 形參的介面,就可以直接把上述的子類套接字實例 struct udp_sock* sk; 作為實參傳進去(當然,這裡需要指針強轉一次(struct sock*)sk)。

沒錯,這裡就是OOP中「is a"的public繼承關係,子類對象可以直接作為父類對象使用。並且,這種實現只支持單繼承。

3.最後是多態……

用C實現多態需要自己維護繼承關係中的虛函數體系,C++有編譯器自動生成、維護vtbl與vptr,到了C里,就只能自己手動維護了。

linux內核的實現中,將系列函數指針放入結構體,即視其為「虛函數」,亦或是專門定義一個xxx_ops結構,裡面放上一堆函數指針,作為「虛函數表」。(某些場合下也會稱其為hook函數)

仍以套接字體系為例:

在基類 sock 中,有協議結構體指針 struct proto *skc_prot;(實際上在sock的基類sock_common中),這個proto即可大體上視為一個虛函數表vtbl,內有具體協議的函數指針(connect、close等),而這個skc_prot指針,即可視為虛指針vptr。

在套接字創建時,根據參數中的協議族、協議類型、協議號信息,調用協議族的create函數執行創建,綁定具體協議proto指針到該vptr上,自此實現了靜態類型到動態類型的綁定。

之後,當調用虛函數時,即可直接通過這些函數指針進行多態的調用。

struct sock *sk;

......

sk-&>sk_prot-&>connect(sk, addr, addr_len); //這裡第一個參數sk即可看做this指針

當然,回到第一點,封裝性,這些函數指針被視為類的「私有成員」,像上面那樣直接調用總不太好,很多情況下,都有一些專門的介面函數(為了效率基本上是內聯實現),去進行虛函數的調用。這點類似C++中屏蔽public虛函數的代碼風格,即虛函數均定義為私有,再提供非虛的public介面以調用……只不過沒有編譯器幫助進行封裝罷了。

以上,本人水平有限,如有錯誤,還望包涵。


Linux何止用到面向對象,連設計模式,系統框架都用上了。。。。

比如輸入子系統,用於抽象觸摸屏,滑鼠,鍵盤等各種輸入設備的輸入框架。。。

比如V4L2 :Video for Linux Version 2,典型是視頻caption框架,用於各種攝像頭等視頻捕獲系統。。

比如MTD系統,對塊存儲設備的讀寫框架。。。。

比如調度子系統: 調度類,及其繼承調度類的各種調度方法。。

尼瑪,這裡面哪個系統不是面向對象,框架化的。。。


參考vfs


參考下kobject也不錯,在sample目錄下還有例子。


最常見的莫過於其驅動框架下的驅動、驅動設備、匯流排包含OOP的東西,但是OOP相對於其驅動框架又是另一個維度上的事情了;另外也可以關注namespace


Linux內核要求代碼提交使用C,而且有一套代碼規範。

我覺得你可以拿這個問題區問問Linus看會不會被噴。不會被噴我們再來研究怎麼在內核中使用OOP;被噴了……我們就等他退休或者掛了再研究……


linux設備驅動歸納總結(三):3面向對象思想和lseek-diytvgy-ChinaUnix博客 一個比較適合入門的linux驅動系列介紹。


OOP僅適合需要很多運行時交互過程的場合,比如遊戲。內核不是一個理想的應用場景。


推薦閱讀:

Linux操作系統關於C library的理解?
如何訪問linux內核,讀取所有進程的task_struct結構?/dev/mem?還是編寫驅動程序?
為什麼 Linux 不用微內核?
在做完內核裁剪後,等待編譯結果的過程是一種怎樣的體驗?
你為什麼學習 Linux 內核?

TAG:編程 | Linux | C編程語言 | 嵌入式系統 | Linux內核 |