不一樣的編程語言具備不一樣的抽象原語(以下),有的原語抽象層次低,有的原語抽象層次高。其中函數式、DSL是這幾年十分熱門的編程語言概念。html
Linux kernel是個與硬件打交道、用C語言開發的幾十年的巨型軟件項目。它的開發語言是C,做爲一門過程式語言,好像離對象式、函數式、DSL這些編程範式很遠,沒法將這些優秀的編程範式的威力發揮在Linux Kernel項目上。node
可是,果然如此麼?linux
wikipedia對面對對象編程的定義:web
Object-oriented programming attempts to provide a model for programming based on objects. Object-oriented programming integrates code and data using the concept of an "object". An object is an abstract data type with the addition of polymorphism and inheritance. An object has both state (data) and behavior (code).express
從中能夠看出,面對對象式編程的基本特徵:編程
無論是用什麼編程語言,只要能知足這些特徵,那就是面對對象範式。C++、Java語言由於提供了對這些特徵直接表達的語法,因此對面對對象編程十分友好。雖然C語言沒有這些原語支持,可是一樣也能作到面對對象。設計模式
封裝的特色:數據結構
封裝的實現方法:閉包
封裝示例:app
抽象、繼承與多態在《C語言面對對象設計模式彙編》一文中有詳細介紹,再也不贅述。
Linux設備模型是Linux Kernel中抽象編程的最佳範本,它分解抽象設備模型6個最基本的對象(以下),其餘全部對象由這些對象組合派生而來。
Linux設備模型繼承關係示圖:
Linux設備模型繼承實現細節局部圖:
wikipedia對函數式編程的定義:
functional programming is a programming paradigm, a style of building the structure and elements of computer programs, that treats computation as the evaluation of mathematical functions and avoids changing-state and mutable data. It is a declarative programming paradigm, which means programming is done with expressions.
函數式編程的基本特徵:
函數式編程經常使用技術:
函數是函數式編程的「一等公民」,能夠在任何位置定義、使用,如變量、函數入參、返回值。這一點C語言徹底能夠作到,Kernel中也有很多編程實例,以下面這個示例中crystalhd_get_cmd_proc就是個高階函數,它的返回值是一個函數指針。
typedef enum BC_STATUS(*crystalhd_cmd_proc)(struct crystalhd_cmd *, struct crystalhd_ioctl_data *); crystalhd_cmd_proc crystalhd_get_cmd_proc(struct crystalhd_cmd *ctx, uint32_t cmd, struct crystalhd_user *uc){ crystalhd_cmd_proc cproc = NULL; for (i = 0; i < tbl_sz; i++) { // 刪除不相關代碼,以便與展現 ... cproc = g_crystalhd_cproc_tbl[i].cmd_proc; break; } } return cproc; }
閉包是高階函數的一種表現形式,能夠理解爲函數與其環境數據的結合體。它主要有2個做用:
C語言的主要有以下應用場景:
以下的示例中,device_for_each_child就符合閉包的定義:是函數fn與其環境數據data的結合體。
int device_for_each_child(struct device *parent, void *data, int (*fn)(struct device *dev, void *data)){ struct klist_iter i; struct device *child; int error = 0; klist_iter_init(&parent->p->klist_children, &i); while ((child = next_device(&i)) && !error) error = fn(child, data); klist_iter_exit(&i); return error; } device_for_each_child(dev, NULL, device_check_offline); result = device_for_each_child(dev, addrp, i2cdev_check_mux_children); device_for_each_child(&dev->dev, &status, slot_reset_iter);
wikipedia對事件驅動編程的定義:
Event-driven programming is a programming paradigm in which the flow of the program is determined by events such as user actions (mouse clicks, key presses), sensor outputs, or messages from other programs/threads. Event-driven programming is the dominant paradigm used in graphical user interfaces and other applications (e.g. JavaScript web applications) that are centered on performing certain actions in response to user input.
事件驅動編程的優勢:
事件的定義:
事件驅動編程的實現原則:
事件驅動編程的實現三部曲:
事件驅動編程的結構化設計:
事件驅動編程的實現技術:
enum kobject_action { KOBJ_ADD, KOBJ_REMOVE, KOBJ_CHANGE, KOBJ_MOVE, KOBJ_ONLINE, KOBJ_OFFLINE, KOBJ_MAX };
"add@/class/input/input9/mouse2\0 // message
ACTION=add\0 // action type
DEVPATH=/class/input/input9/mouse2\0 // path in /sys
SUBSYSTEM=input\0 // subsystem (class)
SEQNUM=1064\0 // sequence number
PHYSDEVPATH=/devices/pci0000:00/0000:00:1d.1/usb2/2-2/2-2:1.0\0 // device path in /sys
PHYSDEVBUS=usb\0 // bus
PHYSDEVDRIVER=usbhid\0 // driver
MAJOR=13\0 // major number
MINOR=34\0", // minor number
熱插拔事件驅動工做流程:
wikipedia對事件驅動編程的定義:
A domain-specific language (DSL) is a computer language specialized to a particular application domain. This is in contrast to a general-purpose language (GPL), which is broadly applicable across domains, and lacks specialized features for a particular domain.
領域特定語言又分爲內部DSL和外部DSL,它們具備共同的特徵:
內部DSL是嵌入到開發語言內部,與開發語言混合使用的DSL,它能夠是一個接口,如printf,也能夠是一個宏,以下示例。
UNUSUAL_DEV( 0x0421, 0x0446, 0x0100, 0x0100, "Nokia", "N80", US_SC_DEVICE, US_PR_DEVICE, NULL, US_FL_IGNORE_RESIDUE | US_FL_FIX_CAPACITY )
UNUSUAL_DEV呈現了2種信息,一種是設備id_table信息,用於驅動匹配,一種是unusual_dev_list,用於標示非標準設備。具體設計和實現細節能夠參考《Linux設備驅動框架設計》一文中的「USB塊設備驅動框架設計」小節,再也不贅述。
外部DSL獨立於開發語言使用,自身具備必定的語言完備性。
Linux Kernel中的設備樹描述模型是個很好的外部DSL的例子。以下圖(左)所示,它描述的是系統中的設備層次關係,這種DSL與領域模型(以下圖右)處在同一語義層次上,表達的語法基本就是領域語言,十分貼切天然。
設備樹描述文件(DTS)通過解釋器(DTC)轉成成字節描述文件(DTB),DTB經過引導加載程序(bootloader)傳給內核用於設備的掃描、配置和初始化。詳細的啓動流程以下:
--完--