金山卫士开源软件之旅(八) netmon下netmon工程的解析---netmon.exe的启动过程分析

转载 引用于 http://blog.csdn.net/chenyujing1234

 

_tWInMain主要做安装,实例判断,初始化COM环境,开始界面显示.

[cpp]  view plain copy
  1. int WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE /*hPrevInstance*/LPTSTR lpstrCmdLine, int nCmdShow)  
  2. {  
  3.     // 获得安装路径  
  4.     // 采用MD5方法将软id和硬id合并为mid  
  5.     // 从dump.dll中的接口KxEOpenDumpMonitorEx2来注册安装此mid  
  6.     KDump::Instance().Install();  
  7.   
  8.     if (S_FALSE == _Module.Init(hInstance))  
  9.         return -1;  
  10.   
  11.     KCheckInstance* _pInst = KCheckInstance::Instance();  
  12.     if (_pInst == NULL)  
  13.         return 0;  
  14.     //  检查是不是第一个实例,并处理多实例  
  15.     int nRetv = _pInst->CheckFirstInstance(lpstrCmdLine/*, NULL, _T("Kingsoft Antivirus KSG Update Mutex")*/);  
  16.     if (!nRetv)  
  17.     {  
  18.         _pInst->ClearFirstInstance();  
  19.         return 0;  
  20.     }  
  21.       
  22.     // 启动的时候,自动起托盘  
  23. //  WCHAR bufPath[MAX_PATH] = {0};  
  24. //  ::GetModuleFileName(NULL, bufPath, MAX_PATH);  
  25. //  ::PathRemoveFileSpecW(bufPath);  
  26. //  ::PathAppend(bufPath, TEXT("KSafeTray.exe"));  
  27. //  ::ShellExecute(NULL, NULL, bufPath, NULL, NULL, SW_HIDE);  
  28.   
  29.     ::CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);  
  30.     // 加载皮肤、类型、串,加载RICHED20.dll, 查看KSafeSvc服务是否在运行, 创建各自的共享内存  
  31.     _Module.Run();  
  32.     ::CoUninitialize();  
  33.   
  34.     _Module.Uninit();  
  35.   
  36.     return 0;  
  37. }  


在_Module.Run主要做加载皮肤、类型、串,加载RICHED20.dll, 查看KSafeSvc服务是否在运行, 创建各自的共享内存

[cpp]  view plain copy
  1. // 加载皮肤、类型、串,加载RICHED20.dll, 查看KSafeSvc服务是否在运行, 创建各自的共享内存  
  2. HRESULT KAppModule::Run()  
  3. {  
  4.     // ======================Small tip==================  
  5.     // 设置资源路径、加载皮肤、类型、串  
  6.     _InitUIResource();  
  7.   
  8.     if ( m_hModRichEdit2 == NULL )  
  9.         m_hModRichEdit2 = ::LoadLibrary(_T("RICHED20.DLL"));  
  10. /* 
  11. #if _DEBUG 
  12.     if (FALSE) 
  13. #else 
  14.     if (_CheckIs64BitOp()) 
  15. #endif 
  16.     { 
  17.         //如果是64位操作系统,就退出。 
  18.         CBkSafeMsgBox2 dlg; 
  19.         dlg.ShowMutlLineMsg(BkString::Get(DefString33), BkString::Get(DefString7), MB_OK | MB_ICONEXCLAMATION); 
  20.         return S_OK; 
  21.     }*/  
  22.   
  23.     // 由于类KMainDlg里有    KFlowStat m_FlowStatLog;  
  24.     // KFlowStat的构造函数中会加载数据库、打开数据库  
  25.     KMainDlg dlgMain;  
  26.     // ======================Small tip==================  
  27.     // 通过OpenSCManager、OpenService、QueryServiceStatus来查看KSafeSvc服务是否在运行  
  28.     if (!dlgMain.CheckServericeIsOK())  
  29.     {  
  30.         netmon_log(L"CheckServiceIsOK Failed!");  
  31.     }  
  32.     // KUrlMonCfgReader类与KNetFluxCacheReaderod类的Init,创建各自的共享内存  
  33.     if (!dlgMain.CheckDriver())  
  34.     {  
  35.         netmon_log(L"CheckDriver failed.Netmon exit.");  
  36.     }  
  37.     else  
  38.     {  
  39.         netmon_log(L"Netmon dlg start ");  
  40.         int uRet = dlgMain.DoModal(NULL);// 窗口显示  
  41.     }  
  42.       
  43.     return S_OK;  
  44. }  

 

在代码的注释中讲到类KFlowStat的构造函数做了数据库的初始化.

这里先不对数据库展开说,以后会专门讲到金山中的数据库.

[cpp]  view plain copy
  1. KFlowStat::KFlowStat()  
  2. {  
  3.  /*HRESULT hr = BKDbCreateObject(__uuidof(ISQLiteComDatabase3), (void**)&m_spiDB); 
  4.  if (!SUCCEEDED(hr)) 
  5.  return; 
  6.  
  7.  int nCmdLen = MAX_PATH * 2; 
  8.  wchar_t szFilePath[MAX_PATH * 2] = {0}; 
  9.  DWORD dwCode = ::GetModuleFileName(NULL, szFilePath, nCmdLen); 
  10.  if (dwCode == 0)a 
  11.  return; 
  12.  
  13.  ::PathRemoveFileSpecW(szFilePath); 
  14.  ::PathAppend(szFilePath, DEF_SQLITE_FILE); 
  15.  
  16.  hr = m_spiDB->Open(szFilePath); 
  17.  if (!SUCCEEDED(hr)) 
  18.  return; 
  19.  */  
  20.   
  21.  HRESULT hr = S_OK;  
  22.   
  23.  // chenyujing1234@163.com 2012-3-29   14:23  
  24.  m_piWlDB = NULL;  
  25.  // ======================Small tip==================  
  26.  // 从注册表中读取LeiDian的APP路径、LeidianLog路径  
  27.  hr = CAppPath::Instance().GetLeidianAppPath( m_modpath.m_strPath );  
  28.  if ( FAILED( hr ) )  
  29.   goto Exit0;  
  30.   
  31.   
  32.  hr = CAppPath::Instance().GetLeidianLogPath( m_dbpath.m_strPath );  
  33.  if ( FAILED( hr ) )  
  34.   goto Exit0;  
  35.   
  36.  m_dbpath.Append( DEF_SQLITE_FILE );  
  37.   
  38.  m_modpath.Append( BKMOD_NAME_BKDB );  
  39. /* { 
  40.   int nCmdLen = MAX_PATH * 2; 
  41.   wchar_t szFilePath[MAX_PATH * 2] = {0}; 
  42.   DWORD dwCode = ::GetModuleFileName(NULL, szFilePath, nCmdLen); 
  43.   ::PathRemoveFileSpecW(szFilePath); 
  44.   ::PathAppend(szFilePath, DEF_SQLITE_FILE); 
  45.   m_dbpath.m_strPath = szFilePath; 
  46.  } 
  47. */   
  48.   
  49.     // ======================Small tip==================  
  50.     // 这里会提示“没有找到MSVCR80.dll”   m_modpath为c:\program files\ksafe\ksafedb.dll,加载失败  
  51.  hr = m_dbmod.LoadLib( m_modpath );  
  52.  if ( FAILED( hr ) )  
  53.   goto Exit0;  
  54.   
  55.  hr = m_dbmod.BKDbCreateObject(   
  56.   __uuidof( Skylark::ISQLiteComDatabase3 ),   
  57.   ( void** )&m_piWlDB   
  58.   );  
  59.  if ( FAILED( hr ) )  
  60.   goto Exit0;  
  61.   
  62.  hr = m_piWlDB->Open( m_dbpath );  
  63.  if ( FAILED( hr ) )  
  64.  {  
  65.   ::SetFileAttributes( m_dbpath, 0 );  
  66.   ::DeleteFile( m_dbpath );  
  67.   hr = m_piWlDB->Open( m_dbpath );  
  68.  }  
  69.   
  70.  if ( FAILED( hr ) )  
  71.   goto Exit1;  
  72.   
  73.  goto Exit0;  
  74.   
  75. Exit1:  
  76.  if ( m_piWlDB )  
  77.  {  
  78.   m_piWlDB->Release();  
  79.   m_piWlDB = NULL;  
  80.  }  
  81.   
  82. Exit0:  
  83.  return ;  
  84. }  


既然dlgMain.DoModal(NULL);了,那么接下来就是OnInitDialog了。

它主要做

1、 KOperMemFile创建共享文件,并存入标志,设备提醒信息,日期
2、 KCheckInstance 把容器句柄等信息写到KCheckInstance映射的内存里
3、 KNetFluxCacheReader  根据映射内在中的信息获取系统和当前进程的流量信息
4、 KFlowTray 确保KSafeTray.exe已经运行
5、 本次和上次的日期信息判断是否需要显示出来
6、 创建CBkNetMonitorListBox,并从listbox_template_netmonitor.xml初始化ListBox,把进程流程信息加到列表里
7、并启动定时器
(定时器时的处理内容下节讲到)

    定时器的类别有:

     (1)更新状态信息
     (2)  更新网络流量信息(间隔:1000)
     (3)更新流量窗口状态(间隔:500)
     (4)检查是否退出了(间隔:500)

[cpp]  view plain copy
  1. BOOL KMainDlg::OnInitDialog( CWindow /*wndFocus*/LPARAM /*lInitParam*/ )  
  2. {  
  3.     if (KOperMemFile::Instance().Init() == S_OK) // 创建共享文件  
  4.     {  
  5.         // ======================Small tip==================  
  6.         // 在映射的MemShareFlowElem内存中存数据 1  
  7.         KOperMemFile::Instance().SetWaitMoniterOpen(1);   
  8.         // ======================Small tip==================  
  9.         // 设置这次与上次提醒的信息:日期  
  10.         _InitFlowRemindInfo();  
  11.     }  
  12.   
  13.     SetIcon(::LoadIcon((HMODULE)&__ImageBase, MAKEINTRESOURCE(IDI_BEIKESAFE)));  
  14.     SetIcon(::LoadIcon((HMODULE)&__ImageBase, MAKEINTRESOURCE(IDI_SMALL)), FALSE);  
  15.   
  16.     m_enumProcessMode = enumProcessModeHasNetFlow;  
  17.   
  18.     // ======================Small tip==================  
  19.     // 把容器句柄等信息写到KCheckInstance映射的内存里  
  20.     KCheckInstance::Instance()->CfgFirstInstance(NULL, this->m_hWnd, FALSE);  
  21.   
  22.     KNetFluxCacheReader reader;  
  23.     if (SUCCEEDED(reader.Init()))  
  24.         //根据映射内在中的信息获取系统和当前进程的流量信息  
  25.         reader.GetProcessesFluxInfo(m_FluxSys, &m_processInfoList, m_enumProcessMode);  
  26. //  KNetFluxCacheReader::Instance().GetSystemNetFlow(m_FluxSys);  
  27.     _DisableDelayScan();  
  28.   
  29.     //  //加入任务栏右键最大化置灰  
  30.     //  LONG lSys = GetWindowLong(GWL_STYLE);  
  31.     //  lSys &= ~(WS_MAXIMIZEBOX);  
  32.     //  SetWindowLong(GWL_STYLE, lSys);  
  33.   
  34.     KFlowTray prot_shell(TRUE);  
  35.     // ======================Small tip==================  
  36.     // 确保KSafeTray.exe已经运行  
  37.     prot_shell.ShellTray();  
  38.   
  39.     //  CListBoxData::GetDataPtr()->SetProviderFunc(NET_MONITOR_219, &KMainDlg::_UpdateNetFlowSummaryWnd);  
  40.   
  41.     // ======================Small tip==================  
  42.     // 本次和上次的日期信息判断是否需要显示出来  
  43.     _ShowNetMintorRemindDlg(TRUE);  
  44.   
  45.     // ======================Small tip==================  
  46.     // 创建CBkNetMonitorListBox,并从listbox_template_netmonitor.xml初始化ListBox  
  47.     // 把进程流程信息加到列表里  
  48.     _InitNetMonitorListBox();  
  49.     // 初始化状态列表,从数据库中获得信息和状态填充列表  
  50.     // 为列表中的项显示当前页面  
  51.     // 通过KNetFluxStasticCacheReader类获得进程流统计列表,  
  52.     _InitStatList();  
  53.   
  54.     // 初始化基本完成,接下来就是开启定时器:  
  55.     //      更新状态信息  
  56.     //      更新网络流量信息(1000)  
  57.     //      更新流量窗口状态(500)  
  58.     //      检查是否退出了(500)  
  59.     m_uTimer = SetTimer(ID_TIMER_UPDATE_NETFlOW_MON, UPDATE_NETFLOW_MON_INTERVAL, NULL);  
  60.   
  61.     SetTimer(ID_TIMER_REFRESH_FLOATWND_STATUS, 500, NULL);  
  62.   
  63.     //_SetAccessNetCount(0);  
  64.     _SetDownAndUpdateSum(0.0, 0.0);  
  65.     _SetDownSpeed(0.0);  
  66.     _SetUpSpeed(0.0);  
  67.   
  68.     _InitFloatWndSwitch();  
  69.   
  70.     m_hEventExit = ::CreateEvent(  
  71.         NULL,  
  72.         FALSE,  
  73.         FALSE,  
  74.         EVENT_NETMON_DLG_EXIT  
  75.         );  
  76.   
  77.     m_hEventChangeFlowatWndDisplayStatusText =::CreateEvent(  
  78.         NULL,  
  79.         FALSE,  
  80.         FALSE,  
  81.         EVENT_NETMON_DLG_FLOATWND_DISPLAY_STATUS_TEXT  
  82.         );  
  83.   
  84.   
  85.     SetTimer(ID_TIMER_CHECK_EXIT, CHECK_EXIT_INTERVAL);  
  86.   
  87.     _InitNetMonSwitch();  
  88.   
  89.     m_bRptThreadWorking = FALSE;  
  90.     m_hEventRptThreadExit = CreateEvent(NULL, TRUE, FALSE, NULL);  
  91.   
  92.     if (m_nCurShowType == enumQueryTypeEveryMonth)  
  93.         OnClickShowStatMonths();  
  94.   
  95.     return TRUE;  
  96. }  


 


初始化过程中把进程信息加到列表中去,这里的列表是继续于框架CBkListBox控制,重载得到的列表.

[cpp]  view plain copy
  1. <p>void KMainDlg::_InitNetMonitorListBox()  
  2. {  
  3.  m_pNetMonitorListBox = new CBkNetMonitorListBox;  
  4.   
  5. .....  
  6.   
  7. }  
  8.   
  9. </p>  
[cpp]  view plain copy
  1. BOOL KMainDlg::_InitStatList( void )  
  2. {  
  3.  m_pNetStatListBox = new CBkNetMonitorListBox;  
  4.   
  5. ..........}  

=========================================================================================

总结:

1、 用到的互斥机制有种:

 (1)采用CLocker

          eg: 在类class KMainDlg中有成员CLocker   m_locker;

           采用关键代码段,相对简单。这里提一下,因为关键代码段采用不让执行代码的方法,当进入嵌套时很容易造成死锁。这在大型框架设备中特别重要。

(2)采用ShareMemLock方式。

 //
// 本锁的特性:
// 当有写的要求时,让旧的读取完成;而新的读取请求被挂起,直到本次写完,即写入优先
// 允许多线程读,只能有一个线程在写

[cpp]  view plain copy
  1. typedef struct _tagShareMemLock  
  2. {  
  3.     // m_nLock用于保护m_nReadCnt变量 ,使在多线程时不互斥  
  4.     volatile LONG           m_nLock;  
  5.     volatile LONG           m_nReadCnt; // 读的次数 ,当为0表没有人在读,  
  6.                                         //           当为 -10000表写在进行  
  7.     volatile LONG           m_nWrite;   // 写锁  
  8.   
  9.     volatile DWORD          m_nDbgLockProcessID;  
  10.     volatile DWORD          m_nDbgLockThreadID;  
  11.     volatile DWORD          m_nDbgLockTime;  
  12.   
  13.     void    InitLock()  
  14.     {  
  15.         m_nLock = 0;  
  16.         m_nReadCnt = 0;  
  17.         m_nWrite = 0;  
  18.     }  
  19.   
  20.     BOOL    TryLockReadCntLock()  
  21.     {  
  22.         // LONG InterlockedCompareExchange  
  23.         // (LPLONG Destination, LONG Exchange, LONG Comperand);  
  24.         // 如果第三个参数与第一个参数指向的值相同  
  25.         // 那么用第二个参数取代第一个参数指向的值。函数返回值为原始值  
  26.         // ============如果m_nLock == 0,那么m_nLock = 1;且返回0。否则返回非0  
  27.         return (::InterlockedCompareExchange(&m_nLock, 1, 0) == 0);  
  28.     }  
  29.   //  让写锁还原   
  30.     BOOL    UnlockReadCntLock()  
  31.     {  
  32.         m_nLock = 0;  
  33.         return TRUE;  
  34.     }  
  35.   
  36.     BOOL    TryLockWriteLock()  
  37.     {  
  38.         return (::InterlockedCompareExchange(&m_nWrite, 1, 0) == 0);  
  39.     }  
  40.   
  41.     //  让写锁还原  
  42.     BOOL    UnlockWriteLock()  
  43.     {  
  44.         m_nWrite = 0;  
  45.         return TRUE;  
  46.     }  
  47.       
  48.     // 请求读的锁,判断现在可否读  
  49.     // 改变完读次数时马上把读锁释放  
  50.     BOOL    TryLockRead()  
  51.     {  
  52.         // 如果有修改请求,那么优先考虑修改  
  53.         if (m_nWrite)  
  54.             return FALSE;  
  55.   
  56.         // 如果已经在修改了,那么先等等,锁之外的判断不  
  57.         // 准确,但是可以起到加速的作用  
  58.         if (m_nReadCnt < 0)  
  59.             return FALSE;  
  60.   
  61.         // 开始进行  
  62.         if (TryLockReadCntLock())  // 获得锁成功  
  63.         {  
  64.             if (m_nReadCnt >= 0)  
  65.             {  
  66.                 m_nReadCnt ++;     // 读的次数加1  
  67.                 UnlockReadCntLock();// 改变完m_nReadCnt后马上把读锁打开   
  68.                 return TRUE;  
  69.             }  
  70.             else                   // 如果小于0,即表示有写请求  
  71.             {  
  72.                 UnlockReadCntLock();// 马上把读锁打开   
  73.                 return FALSE;  
  74.             }  
  75.         }  
  76.         return FALSE;  
  77.     }  
  78.     // 锁住读  
  79.     BOOL    LockRead()  
  80.     {  
  81.         // 如果已经有一个读在进行,那么就等待  
  82.         while (!TryLockRead())  
  83.             ::Sleep(1);  
  84.         return TRUE;  
  85.     }  
  86.   
  87.     void    UnLockRead()  
  88.     {  
  89.         while (!TryLockReadCntLock())// 保护m_nReadCtn  
  90.             ::Sleep(1);  
  91.         m_nReadCnt --;  
  92.         UnlockReadCntLock();          // 保护m_nReadCtn  
  93.     }  
  94.   
  95.     /// 把读锁锁上.  
  96.   
  97.     BOOL    TryLockWrite()  
  98.     {  
  99.         // 如果有人在读,那么再等等  
  100.         // 但是可以起到加速作用  
  101.         if (m_nReadCnt > 0)  
  102.             return FALSE;  
  103.   
  104.         if (TryLockReadCntLock())  
  105.         {  
  106.             // 确保没有人读,也没有人写  
  107.             if (m_nReadCnt == 0)  
  108.             {  
  109.                 m_nReadCnt = -10000;  
  110.                 UnlockReadCntLock();  
  111.                 return TRUE;  
  112.             }  
  113.             else  // 还有读在进行,那么  
  114.             {  
  115.                 UnlockReadCntLock();  
  116.                 return FALSE;  
  117.             }  
  118.         }  
  119.         return FALSE;  
  120.     }  
  121.   
  122.     // 想锁住写,  
  123.     //     前提是:上一次的写已经调用了UnLockWrite(即写锁已经解开)  
  124.     // 如果成功,那么把写锁与读锁都锁上  
  125.     BOOL    LockWrite()  
  126.     {  
  127.         // 保证没有其他人在写  
  128.         while (!TryLockWriteLock())  
  129.             ::Sleep(1);  
  130.   
  131.         // 与LockRead不一样,这样如果发现在忙时不退出而是等待,这样就有了优先级  
  132.         // 保证其他人没有在读,也没有在写  
  133.         while (!TryLockWrite())  
  134.             ::Sleep(1);  
  135.         return TRUE;  
  136.     }  
  137.   
  138.     // 写锁解开  
  139.     void    UnLockWrite()  
  140.     {  
  141.         while (!TryLockReadCntLock())  
  142.             ::Sleep(1);  
  143.         m_nReadCnt = 0;  
  144.         UnlockReadCntLock();  
  145.   
  146.         UnlockWriteLock();  
  147.     }  
  148. }ShareMemLock;  


 

 

          eg: 示例一:在类KStasticFluxProcessList中有成员ShareMemLock   m_lock;

[cpp]  view plain copy
  1. struct KStasticFluxProcessList  
  2. {  
  3.     DWORD                   m_nSize;  
  4.     ShareMemLock            m_lock;  
  5.     ULONGLONG               m_nTotalRecv;           // 总计接受的流量  
  6.     ULONGLONG               m_nTotalSend;           // 总计发送的流量  
  7.     __int64                 m_nTimeWatch;           // 监控时间  
  8.     __int64                 m_nTimeTodayStart;      // 今天截止时间点  
  9.     __int64                 m_nTimeTodayLastTime;   // 今天截止时间点  
  10.   
  11.     DWORD                   m_nMaxCnt;  
  12.     DWORD                   m_nCurrentCnt;  
  13.     DWORD                   m_nReserved[100];  
  14.     KFluxStasticProcItem    m_Items[1];  
  15. };  


在上面OnInitDialog( 讲到BOOL KMainDlg::_InitStatList( void ),里它会调用_GetAndShowProcessInfo(); 它就是 通过KNetFluxStasticCacheReader类获得进程流统计列表,
_GetAndShowProcessInfo();里就用到了此锁 m_lock来控制访问.

[cpp]  view plain copy
  1. // 初始化状态列表,从数据库中获得信息和状态填充列表  
  2. // 为列表中的项显示当前页面  
  3. // 通过KNetFluxStasticCacheReader类获得进程流统计列表,  
  4. BOOL KMainDlg::_InitStatList( void )  
  5. {  
  6.     m_pNetStatListBox = new CBkNetMonitorListBox;  
  7.     if (NULL == m_pNetStatListBox)  
  8.         return FALSE;  
  9.   
  10.     _GetCurLogInfo(enumQueryTypeEveryDay);  
  11.       
  12.     // ======================Small tip==================  
  13.     // 初始化状态列表,从数据库中获得信息和状态填充列表  
  14.     //listbox  
  15.     m_pNetStatListBox->Create( GetViewHWND(), TAB_SHOW_STAT_WINDOW);  
  16.     m_pNetStatListBox->Load(IDR_BK_LISTBOX_STATINFO);  
  17.     m_pNetStatListBox->SetCanGetFocus(FALSE);  
  18.   
  19.     // ======================Small tip==================  
  20.     // 为列表中的项显示当前页面  
  21.     _ShowPageForList();  
  22.   
  23. //  m_fluxStatRead.Init();  
  24.   
  25.     // ======================Small tip==================  
  26.     // 通过KNetFluxStasticCacheReader类获得进程流统计列表,  
  27.     _GetAndShowProcessInfo();  
  28.       
  29.     _ShowRemindInfo();  
  30.   
  31.     SetTimer(ID_TIMER_UPDATE_STAT_INFO, 30000, NULL);  
  32.   
  33.     PostMessage(WM_TIMER, ID_TIMER_UPDATE_STAT_INFO, 0);  
  34.   
  35.     return TRUE;  
  36. }  
[cpp]  view plain copy
  1. void KMainDlg::_GetAndShowProcessInfo( void )  
  2. {  
  3.   
  4. pFluxStatRead->m_lock.LockRead();  
  5.   
  6. ....... //  处理数据  
  7.   
  8. pFluxStatRead->m_lock.UnLockRead();  
  9.   
  10. }  



 

 

示例二:在类KProcessFluxList中有成员ShareMemLock   m_lock;

[cpp]  view plain copy
  1. struct KProcessFluxList  
  2. {  
  3.     DWORD                   m_nSize;  
  4.     ShareMemLock            m_lock;  
  5.     KPFWFLUX                m_SysFlux;  
  6.     DWORD                   m_nMaxCnt;  
  7.     DWORD                   m_nCurrentCnt;  
  8.     DWORD                   m_nProcessPopCount;  
  9.     DWORD                   m_nReserved[99];  
  10.     KProcFluxItem           m_Items[1];  
  11. };  


在上面OnInitDialog( 讲到BOOL KMainDlg::_InitStatList( void ),里它会调用reader.GetProcessesFluxInfo(m_FluxSys, &m_processInfoList, m_enumProcessMode);

它就是 根据映射内在中的信息获取系统和当前进程的流量信息.

GetProcessesFluxInfo里就用到了_GetProcessesFluxInfo(sysFlux, pProcessesList, nProcessMode);

GetProcessesFluxInfo就是用到了此锁来访问信息。

 

[cpp]  view plain copy
  1. // 获取系统和当前进程的流量信息  
  2.  BOOL _GetProcessesFluxInfo(KPFWFLUX& sysFlux, std::vector<KProcFluxItem>* pProcessesList, int nProcessMode = enumProcessModeHasAll)  
  3.  {  
  4.   
  5.          // 为保证快速读取,并且释放锁,这里先使用内存拷贝的方法  
  6.   
  7.        pList->m_lock.LockRead();  
  8.   
  9.        .......// 处理数据  
  10.   
  11.       // 解锁  
  12.   
  13.       pList->m_lock.UnLockRead();  
  14.   
  15. }    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值