歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> Linux編程 >> 從printk和logMsg看Linux和vxworks的設計理念差異

從printk和logMsg看Linux和vxworks的設計理念差異

日期:2017/3/1 10:09:42   编辑:Linux編程

printk是linux內核的打印函數,類似用戶態下的printf,可在中斷上下文調用;同樣,logMsg是vxworks內核的打印函數,也可在中斷上下文調用。
linux開始作為桌面系統設計,後來廣泛用於服務器領域,慢慢擴展到了嵌入式系統;而vxworks則以高性能實時嵌入式系統聞名。
從這可以看出,它們的差異是很大的,考查兩個同樣的功能在不同系統的實現,管中窺豹,雖有不足,但也可以了解兩個系統(分時系統與實時系統)設計上的一些考慮。

下面先看看printk的實現(內核版本2.6.38):
1,關內核搶占,關閉中斷;
2,把打印信息格式化到一個臨時緩存區;
3,添加打印級別,打印時間(可選,編譯配置);
4,把格式化後的信息從臨時緩存區拷貝到環回緩存區(log_buf,意味著緩存區滿了之後,新的數據會覆蓋老數據),
5,釋放控制台的信號量,喚醒klogd守護線程;
6,打開中斷,使能內核搶占;
7,klogd得到調度則會把環回緩存區的信息在控制台上顯示。

再來看看vxworks下的logMsg的實現(版本號5.5.1):
1, 系統初始化時會創建一個消息隊列(典型的生產者消費者模型,類似上面的環回緩存區,但不支持覆蓋寫入);一個系統打印線程,類似上面的klogd;
2,首先判斷調用logMsg的上下文,如果是中斷,則入消息隊列時不等待,就是說嘗試獲取消息隊列的信號量,不成功就返回;
3,如果獲取隊列信號量成功,說明沒有其他人在操作消息隊列,拷貝當前打印參數到消息隊列中去,共拷貝7個參數:
打印字符串的指針;參數1-參數6(就是說,logMsg最多只支持6個打印參數);
4,logMsg返回;
5,系統打印線程得到調度後發現消息隊列中存在待打印的消息,取出打印信息;
6,打印信息進行格式化;
7,顯示格式化的信息;

從上面的流程上看,linux與vxworks的內核打印處理需要完成的動作是類似的,差異的是動作的編排上,那部分動作先做,那部分動作後做。
linux的printk是一種很常規的處理流程,而logMsg則特別做了設計,logMsg的處理非常簡單高效,拷貝7個參數到消息隊列中,然後就返回了,剩下的事情由打印線程完成,而linux的大部分動作都在printk完成,打印線程只負責顯示。

它們兩者的缺點也很明確:

1)printk關內核搶占,關中斷,在大量打印情況下可能導致中斷丟失,一些依賴於中斷的處理可能會不及時,如高精度定時器;
2)而logMsg在中斷下的打印是嘗試在消息隊列中保存打印參數,不做格式化,所以必須明確最大支持的打印參數個數,且打印信息必須是
const char* 類型的,就是說打印信息不能動態生成的;
3)兩者在大量打印的情況下都會有丟信息,logMsg滿了就不接受新的打印信息,而printk則是新的打印信息覆蓋久的打印信息。

為什麼要這樣做呢,目的何在?

vxworks作為一個實時系統,實時系統要求能夠在指定或者確定的時間內完成系統功能和外部或內部、同步或異步時間做出響應,中斷的及時響
應是至關重要的。想想一個戰斗機的場景,飛行員下發發射命令(對系統來說就是一個按鍵中斷),系統100毫秒(十分之一秒)才做出反應,
而敵機立即做出反應,我方的炸彈還未發射就機毀人亡了。因此,vxworks這麼調整,保證打印不會阻塞中斷,也就理所當然了。
而linux開始作為一個分時的桌面系統設計,對普通用戶來說,一個按鍵是10毫秒響應還是100毫秒響應,是很難感受出來的。

從這個簡單的例子可以看出,一個系統開始的設計理念,會影響到代碼的方方面面,從中細細品味,也有不少收獲。

Copyright © Linux教程網 All Rights Reserved