程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> 寫一個Windows上的守護進程(1)開篇,守護進程開篇

寫一個Windows上的守護進程(1)開篇,守護進程開篇

編輯:C++入門知識

寫一個Windows上的守護進程(1)開篇,守護進程開篇


寫一個Windows上的守護進程(1)開篇

最近由於工作需要,要寫一個守護進程,主要就是要在被守護進程掛了的時候再把它啟起來。說起來這個功能是比較簡單的,但是我前一陣子寫了好多現在回頭看起來比較糟糕的代碼,所以就想這次寫的順眼一點。寫完後發現,诶,還可以喲。於是就總結總結。

一.大致需求

1. 功能——當被守護進程掛掉後再次啟動它

2. 可配置需要守護的進程

二.通盤考慮

1. 為了避免重復造輪子,況且有的輪子可能自己也造不出來,上boost庫

2. 為了能夠獲得較高的權限和能夠開機自動啟動,將其編寫為一個Windows服務

3. 配置文件使用xml存儲,使用rapidxml庫解析

4. 為了使其更具有通用性,我又加了個功能:執行周期任務。周期任務又分了兩種,一種是時間點任務,就是每到幾點幾分執行任務,另一種是時間間隔任務,就是每隔多少分鐘執行任務

三.第一個話題:日志模塊

俗話講,糧草未動,兵馬先行。竊以為日志模塊就像糧草一樣,所以最先開始寫日志模塊。

然而有人會問日志模塊這種輪子多得很,不是說好不重復造輪子的嗎?這當然是有原因的。

1. 我所見過的日志模塊無非就提供幾種字符串Log接口,實踐而知,在Windows上,我們經常會用到GetLastError去獲取錯誤碼,以前我總是寫

ErrorLog("xxx fail, error code: %lu", GetLastError());

寫得多了,就覺得麻煩了,能不能簡化一下?

2. 有的時候我就想往日志文件裡頭記一段二進制數據,不管可不可讀。但是沒有直接記錄字節數據的日志接口

3. 熟悉Windows編程的同學都知道,API有A/W之分,那是因為字符(串)參數有寬窄之分,有一些日志庫根本就沒有考慮這個,只提供char版本的接口,我要是想傳入wchar_t的字符串,還得自己再轉一下,這寫多了也麻煩啊

基於以上幾點,我決定自行造輪子,要造一個舒舒服服的輪子。

以下是日志類的聲明:

class CLoggerImpl : public Singleton<CLoggerImpl>
{
    friend class Singleton<CLoggerImpl>;

private:
    CLoggerImpl();

public:
    ~CLoggerImpl();

public:
    //if dir is empty, use exe dir
    //when log file increases over max_size, we will create new log file
    //if max_size is 0, use 10 * 1024 * 1024 (10MB)
    bool init(const std::string& dir, const unsigned long max_size);
    bool init(const std::wstring& dir, const unsigned long max_size);

    bool log_string(const LOG_LEVEL level, const char* file, const int line, const std::string& s);
    bool log_string(const LOG_LEVEL level, const char* file, const int line, const std::wstring& ws);

    bool log_bytes(const LOG_LEVEL level, const char* file, const int line, const void *buf, const unsigned long len, const std::string& prefix);
    bool log_bytes(const LOG_LEVEL level, const char* file, const int line, const void *buf, const unsigned long len, const std::wstring& wprefix);

    bool log_last_error(const LOG_LEVEL level, const char* file, const int line, CLastErrorFormat& e, const std::string& prefix);
    bool log_last_error(const LOG_LEVEL level, const char* file, const int line, CLastErrorFormat& e, const std::wstring& wprefix);
};

請先關注其接口,忽略其他部分。這裡用了重載的方式免去調用者對char和wchar_t的區分。

四.結束語

我決定一點一點的說,這次就這麼多2015年10月24日星期六

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved