程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> VC >> 關於VC++ >> 一個多線程的日志記錄DLL

一個多線程的日志記錄DLL

編輯:關於VC++

日志記錄對於應用程序來說是很重要的。本文就簡單實現的實現了這樣一個模塊。該模塊實現對程序預期的信息進行記錄的功能。該模塊為每一個向它進行注冊的模塊開啟一個線程並同時創建或者打開一個同名但擴展名為.log的文本文件,此文件位於程序可執行文件目錄下的/Log子目錄下。這樣也具有了一定的靈活性,比如可以再Debug版本中用此庫輸出調試信息到文件,而在Release版本中真正用於記錄日志信息。

下面對其中的兩個類的接口介紹一下:

CInfoReport:

該類在實現時已經用AFX_EXT_CLASS關鍵字指明,是一個DLL導出類,繼承自CObject。

數據成員:

// 存放線程的指針鏈表,所有對象公用一份,故聲明為static
static CPtrList m_lstpThreads;

成員函數:

// 注冊模塊
DWORD Register(LPCTSTR ModuleNameToReg);
// 寫入信息,其中的第一個參數MoudleID必須是Register函數的返回值,
// 如果為NULL則將信息記錄到FatalErr.log文件中。
void WriteInfo(DWORD MoudleID, CString InfoDescribe);
// 寫入信息,其中的第一個參數MoudleID必須是Register函數的返回值,
// 如果為NULL則將信息記錄到FatalErr.log文件中。
void WriteInfo(DWORD MoudleID, CString InfoFrom, CString InfoDescribe);

CWriteInfo:

該類繼承自CWinThread,用於為每一個已注冊的模塊開啟一個線程並且維護一個擴展名為log的日志文件。因為可能有多個線程同時進行同一文件操作,故此類還提供了互斥機制來確保文件I/O無沖突的進行。

數據成員:

// 注冊的模塊名,日志文件與它同名但擴展名不同
CString m_strModuleName;
CFile m_file; // 日志文件對象
// 為實現文件互斥操作的事件句柄
HANDLE m_hEventBusy;

成員函數:

// GetName()和SetModuleFileName()對私有成員m_strModuleName進行存取。
CString GetName();
void SetModuleFileName(CString strFileName);

消息處理函數:

// 處理由CInfoReport::WriteInfo()發來的消息TM_WRITE_INFO
afx_msg void OnWriteInfo(WPARAM wParam, LPARAM lParam);

注:未盡事項請參考源代碼,包括庫本身以及一個測試程序InfoReportTest。簡單起見,測試程序(一個文檔/視的SDI程序)的視圖類的OnDraw()函數裡調用了該庫的日志記錄函數。

程序需要完善的地方

該程序在匆忙之間完成,還有問題沒有解決:

1. 安全性檢查,比如可執行文件的目錄下沒有/Log子目錄,程序將產生異常。

2. 該程序的導出類在EXE文件中被作為全局變量沒有問題,而在DLL中作為全局變量應用則會導致沒有反應,跟蹤發現是由於創建新線程時在::WaitForSingleObject()處僵死,作為局部變量(類的成員變量使用則沒有問題)。

本文配套源碼

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