本文討論實現的記錄log功能的模組設計,以及如何?對於其它模組封裝細節實現資訊隱藏。由於有些方面(例如項目中要求必須使用C,與遺留系統相容等),只能使用C實現,所以沒有用物件導向語言C++, java, C#中類的實現方式。但使用了物件導向的思想,如如何提供介面操作相關屬性,如何最大程度實現資訊隱藏等。
一. 封裝
所有記錄log的函數在log_record.c中,那麼需要考慮提供哪些函數給其它模組調用。
可以有三個函數
1. void log_init(char * path); /* 根據路徑初始化log:開啟log記錄檔案等*/2. void log_print(char *file, int line, char * format, ...); /* 通過可變參數記錄log資訊 */3. void log_end(); /* 程式結束後的log清理:關閉檔案等 */
這樣一來,其它模組只需要使用這三個函數就能實現log的記錄功能了,具體如何?就不用關心了。當然,此處函數參數已經到了最簡。如果這三個函數之間有資訊傳遞,如操作同一個檔案描述符,則這個檔案描述符要設定成全域變數的形式。
二. 多進程
log
操作,進程之間主要有兩種情況(針對
2
個進程,多個進程類似):
- 兩個進程相互獨立。
- 兩個進程之間有關係。(例如:在Linux中兩個進程的父子關係)
如果兩個不同的進程有自己獨立的log記錄功能則使用上面討論的log模組就可以完全實現了。但如果兩個進程使用同一個log檔案呢?
例如:有一個父進程,然後 fork()出一個或多個子進程,那麼這時這種實現方式就會有問題存在,存在同時讀寫log檔案的問題。如何解決呢?
有兩種方式可以解決
- 對檔案加鎖
- 使用共用記憶體,對共用記憶體加鎖,當共用記憶體滿了之後可以再寫入磁碟。
對於第一種方式,檔案加鎖,如果進程操作頻繁,那麼顯然加鎖,寫入檔案會有效率低的問題。對於第二種方式,則可以很好解決這個問題。共用記憶體作為一個緩衝區,可以實現高速讀寫,這樣一來,就解決了效率低的問題。