關於可變參數(不定參數),以及windows下將進程的cpu,記憶體統計資訊寫到日誌

來源:互聯網
上載者:User

單純的寫日誌,沒必要使用可變參數,但是不利於封裝,代碼難看,今天研究了一下可變參數

先查看手冊:http://www.cplusplus.com/reference/cstdio/vsprintf/?kw=vsprintf 

function<cstdio>vsprintf
int vsprintf (char * s, const char * format, va_list arg );
Write formatted data from variable argument list to string

Composes a string with the same text that would be printed if format was used on printf, but using the elements in the variable argument list identified
by arg instead of additional function arguments and storing the resulting content as a C string in the buffer pointed by s.

Internally, the function retrieves arguments from the list identified by arg as if va_arg was used on it, and thus the state of arg is likely to
be altered by the call.

In any case, arg should have been initialized by va_start at some point before the call, and it is expected to be released by va_end at
some point after the call.


Parameters

s
Pointer to a buffer where the resulting C-string is stored.
The buffer should be large enough to contain the resulting string.
format
C string that contains a format string that follows the same specifications as  format in printf (see printf for
details).
arg
A value identifying a variable arguments list initialized with va_start.
va_list is a special type defined in <cstdarg>.



Return Value

On success, the total number of characters written is returned.
On failure, a negative number is returned.


Example

1234567891011121314151617181920212223242526272829
/* vsprintf example */#include <stdio.h>#include <stdarg.h>void PrintFError ( const char * format, ... ){  char buffer[256];  va_list args;  va_start (args, format);  vsprintf (buffer,format, args);  perror (buffer);  va_end (args);}int main (){  FILE * pFile;  char szFileName[]="myfile.txt";  pFile = fopen (szFileName,"r");  if (pFile == NULL)    PrintFError ("Error opening '%s'",szFileName);  else  {    // file successfully open    fclose (pFile);  }  return 0;}

In this example, if the file myfile.txt does not exist, perror is called to show an error message similar to:

Error opening file 'myfile.txt': No such file or directory

概括起來就是: 可變參數定義時候,參數列表包含... va_list等提供支援。而va_list需要標頭檔<stdarg.h>. 上面代碼的va_start(args, format); 說,從fromat開始當做可變參數。 vsprintf(buffer, format, args); 說, 將format之後的可變參數轉化為一般字元串buffer。上面代碼直接printf(“%s", buffer); 得到的是 Error opening
file "myfile.txt". 很常規。  然後主函數調用中,將需要加入的變數,通過與printf類似的方式,加入。例如,需要加入兩個int參數 可以 function(”%d %d“,  a, b); 依次類推。可變字串用起來很簡單。那麼其背後的原理呢? 可參見http://renjwjx.blog.51cto.com/811549/243827 也不難理解。。注意: log類在哪裡都可以用。 而記錄cpu資訊的程式運行在vs2005(之後版本應該也可以),因為vc6.0對psapi.h的支援不好,可以擷取cpu資訊,但是擷取不了記憶體及傳輸資料資訊。另外,要使用psapi需要windows sdk。如果發現運行不找不到psapi.h,那麼需要裝windows sdk。

1.       需要psapi.h 。 需要安裝windows sdk。 安裝完了之後發現,有的東西還是不能用。是因為sdk對vc6.0的支援不夠。後改用vs2005後解決。

2.       sdk 環境的設定。 在include 和lib 目錄裡面分別設定psapi.h 和psapi.lib的路徑。比如:(vs2005)的路徑可以通過運行

的最後一個configuration 進行設定,當然也可以手工加入,效果如下:

還需要添加附加依賴項,或者直接#pragma
comment(lib, "Psapi.lib")

 

接下來寫我的log 類:

//mylog.h#ifndef MYLOG_H#define MYLOG_H#include <time.h>#include <stdio.h>#include <stdarg.h>class Mylog_{public:Mylog_::Mylog_(const char * logname) {logname_ = logname;FILE *fp = NULL; fp = fopen(logname_, "a+");fclose(fp);}Mylog_::~Mylog_(){if(fp != NULL)fclose(fp);}void Mylog_::writeLogTime(){fp = fopen(logname_, "a+");time(&rawtime);p = localtime(&rawtime);fprintf(fp, "%d/%d/%d ", 1900 + p->tm_year, 1 + p->tm_mon, p->tm_mday);fprintf(fp, "%d:%d:%d", p->tm_hour, p->tm_min, p->tm_sec);fclose(fp);}void Mylog_::recordMessage ( const char * format, ... ){char buffer[256];va_list args;va_start (args, format);vsprintf (buffer,format, args);fp = fopen(logname_, "a+");fprintf(fp, "%s\n", buffer);fclose(fp);va_end (args);}public:const char * logname_;time_t rawtime;tm *p;FILE * fp;};#endif
為了得到cpu,記憶體資訊,還需要:
//process_stat.h#ifndef PROCESS_STAT_H#define PROCESS_STAT_H#include <windows.h>typedef LONG64 int64_t;typedef ULONG64 uint64_t;int get_cpu_usage(int pid);int get_memory_usage(int pid, uint64_t* mem, uint64_t* vmem);int get_io_bytes(int pid, uint64_t* read_bytes, uint64_t* write_byte);int  GetPidFromName(LPCSTR lpProcessName);#endif

//代碼源自:http://www.rosoo.net/a/201112/15557.html 在此基礎上進行修改//process_stat_win.cpp#include <windows.h>#include <psapi.h>#include <assert.h>#include "process_stat.h"#include "process.h"#include "Tlhelp32.h"#include <string>using namespace std;//#define _WIN32_WINNT 0x0501#pragma comment(lib, "Psapi.lib")static uint64_t file_time_2_utc(const FILETIME* ftime){LARGE_INTEGER li;assert(ftime);li.LowPart = ftime->dwLowDateTime;li.HighPart = ftime->dwHighDateTime;return li.QuadPart;}static int get_processor_number(){SYSTEM_INFO info;GetSystemInfo(&info);return (int)info.dwNumberOfProcessors;}int get_cpu_usage(int pid){static int processor_count_ = -1;static int64_t last_time_ = 0;static int64_t last_system_time_ = 0;FILETIME now;FILETIME creation_time;FILETIME exit_time;FILETIME kernel_time;FILETIME user_time;int64_t system_time;int64_t time;int64_t system_time_delta;int64_t time_delta;int cpu = -1;if(processor_count_ == -1){processor_count_ =  get_processor_number();}GetSystemTimeAsFileTime(&now);HANDLE  hProcess = OpenProcess(PROCESS_ALL_ACCESS, false, pid);//原來版本中,hProcess 為 GetCurrentProcess()if(!GetProcessTimes(hProcess, &creation_time,&exit_time,&kernel_time, &user_time)){return -1;}system_time = (file_time_2_utc(&kernel_time)+file_time_2_utc(&user_time)) / processor_count_;time = file_time_2_utc(&now);if((last_system_time_ == 0 ) || last_time_ == 0){last_system_time_ = system_time;last_time_ = time;return -1;}system_time_delta = system_time - last_system_time_;time_delta = time - last_time_;assert(time_delta != 0);if(time_delta == 0)return -1;cpu = (int) ((system_time_delta * 100 + time_delta / 2) / time_delta);last_system_time_ = system_time;last_time_ = time;return cpu;}int get_memory_usage(int pid, uint64_t* mem, uint64_t* vmem){PROCESS_MEMORY_COUNTERS pmc;HANDLE  hProcess = OpenProcess(PROCESS_ALL_ACCESS, false, pid);if(GetProcessMemoryInfo(hProcess, &pmc, sizeof(pmc))){if(mem) *mem = pmc.WorkingSetSize;if(vmem) *vmem = pmc.PagefileUsage;return 0;}return -1;}int get_io_bytes(int pid, uint64_t* read_bytes, uint64_t* write_byte){IO_COUNTERS io_counter;HANDLE  hProcess = OpenProcess(PROCESS_ALL_ACCESS, false, pid);if(GetProcessIoCounters(hProcess, &io_counter)){if(read_bytes) *read_bytes = io_counter.ReadTransferCount;if(write_byte) *write_byte = io_counter.WriteTransferCount;return 0;}return -1;}/*void ReStartProcess(CString proname){bool isKill = KillProcessFromName(proname);if(isKill)printf("kill %s success\n", proname.GetBuffer(0));elseprintf("kill %s failed\n", proname.GetBuffer(0));CString strpath1;strpath1 = proname;Sleep(1000);CreateNewProcess(strpath1);Sleep(5000);int i = 1;while (FindProcessFromName(proname) == FALSE && i < 3){i++;CreateNewProcess(strpath1);Sleep(5000);}}BOOL CreateNewProcess(LPCSTR pszExeName){PROCESS_INFORMATION piProcInfoGPS;STARTUPINFO siStartupInfo;SECURITY_ATTRIBUTES saProcess, saThread;ZeroMemory( &siStartupInfo, sizeof(siStartupInfo) );siStartupInfo.cb = sizeof(siStartupInfo);saProcess.nLength = sizeof(saProcess);saProcess.lpSecurityDescriptor = NULL;saProcess.bInheritHandle = true;saThread.nLength = sizeof(saThread);saThread.lpSecurityDescriptor = NULL;saThread.bInheritHandle = true;return ::CreateProcess( NULL, (LPTSTR)pszExeName, &saProcess, &saThread, false,CREATE_DEFAULT_ERROR_MODE,NULL, NULL, &siStartupInfo, &piProcInfoGPS );}BOOL FindProcessFromName(LPCSTR lpProcessName){HANDLE hSnapShot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); PROCESSENTRY32 pe; pe.dwSize = sizeof(PROCESSENTRY32); if(!Process32First(hSnapShot,&pe)) { return FALSE; } CString strProcessName = lpProcessName; strProcessName.MakeLower(); while (Process32Next(hSnapShot,&pe)) { CString scTmp = pe.szExeFile; scTmp.MakeLower(); if(!scTmp.Compare(strProcessName)) { return TRUE; } scTmp.ReleaseBuffer(); } strProcessName.ReleaseBuffer(); return FALSE; }BOOL KillProcessFromName(LPCSTR lpProcessName){HANDLE hSnapShot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); PROCESSENTRY32 pe; pe.dwSize = sizeof(PROCESSENTRY32); if(!Process32First(hSnapShot,&pe)) { return FALSE; } CString strProcessName = lpProcessName; strProcessName.MakeLower(); while (Process32Next(hSnapShot,&pe)) { CString scTmp = pe.szExeFile; scTmp.MakeLower(); if(!scTmp.Compare(strProcessName)) { DWORD dwProcessID = pe.th32ProcessID; //獲得pidHANDLE hProcess = ::OpenProcess(PROCESS_TERMINATE,FALSE,dwProcessID); //不管通過pid還是進程名字最終都是為了獲得進程的控制代碼::TerminateProcess(hProcess,0); CloseHandle(hProcess); return TRUE; } scTmp.ReleaseBuffer(); } strProcessName.ReleaseBuffer(); return FALSE; }*/int  GetPidFromName(LPCSTR lpProcessName){HANDLE hSnapShot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); PROCESSENTRY32 pe; pe.dwSize = sizeof(PROCESSENTRY32); if(!Process32First(hSnapShot,&pe)) { return FALSE; } //CString strProcessName = lpProcessName; string strProcessName(lpProcessName);//strProcessName.MakeLower(); while (Process32Next(hSnapShot,&pe)) { //這裡需要//CString scTmp = pe.szExeFile; char buffer[260];wcstombs(buffer, pe.szExeFile, sizeof(buffer));string scTmp(buffer);//scTmp.MakeLower(); if(!scTmp.compare(strProcessName)) { DWORD dwProcessID = pe.th32ProcessID; //獲得pidreturn dwProcessID;} }  return -1; }

//main.cpp#include "process_stat.h"#include <windows.h>#include <stdio.h>#include "mylog.h"const char processName[] = "PlateSvr.exe";const char logName[] = "log1.txt";int main(){int pid = -1;pid = GetPidFromName(processName);if(pid == -1){printf("cann't find the process. please confirm the processName\n");return 0;}printf("processName = %s pid = %d\n", processName, pid);printf("正在記錄到%s", logName);while(1){int cpu;uint64_t mem, vmem, r, w;cpu = get_cpu_usage(pid);get_memory_usage(pid,&mem, &vmem);get_io_bytes(pid,&r, &w); //在本程式中沒用,在別的地方有用。。Mylog_ log(logName);log.writeLogTime();log.recordMessage("cpu: %d%%記憶體:%u KB\n", cpu, mem/1000);Sleep(1000); //記錄間隔}return 0;}

這些東西放在一起,應該是可以啟動並執行,如果不能運行,有可能是環境出了什麼問題。運行效果:

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.