背景
OJ的算法题总是会返回一个结果告诉你时间和占用的内存,要是有问题还会告诉你代码的BUG。你可能也知道一份提交的代码可以通过调用函数来测试它所用的时间,但是如果总是要删除再增加它的内容好像也是挺浪费时间的。本来几个同学在维护Matrix那边的OJ项目,可以问一下他们的,但是他们现在他们没空2333,让我先想想吧。我想要实现如下效果:把代码A产生的A.exe装载到主要的代码main里, 算作子进程 ChildProcess , 此时Test.exe是父进程, 我们在命令行里输入:
Test.exe A.exe input
就可以让A.exe被装载并且进行测试。如果可以的话还可以用脚本设定多个要测试的程序样本, 然后测定各自使用的时间。这样肯定要调用系统代码了, 包括process.h的代码有一些函数, 另外测试内存的代码也有<Psapi.h>。
在windows下的编程我感觉有点抓瞎。我现在还得先去学一下windows的API或者直接用Linux算了。
测试了一下代码,test.cpp里如果用execl(或者是_execl), 参数为 char* path, char* argv[], 即argv->execl->被执行文件, 被执行文件抛出了一个错误 Access violation reading location 0x00000001。经过debug是因为execl(path, argv[0], argv[1], ... )最后一个参数应该为(char*)NULL,表明参数结束。
= = = = = = = = = = = = = = = = = = = = =
UPDATE 实际测试
cmd运行test.exe A.exe input, 发现A.exe是运行了,可是最后命令行的运行路径就好像echo off了一样。虽然能运行吧,感觉还是有问题。
test.cpp
1 #include<stdio.h> 2 #include<process.h> 3 #include<stdio.h> 4 int main(int argv, char* args[]) { 5 // char* absolute _path and file, char* argvs:must end with NULL 6 //char* path = ______, name = A.exe, ... 7 8 int c = execl(path, name, (char*)"input", (char*)NULL); 9 printf("You are %d debugging here ", c); 10 return 0; 11 }
又跑去看了两篇论文,一篇是硕士论文,讲一个OJ的自动批改,但是没有代码我也很难做。
想了一下,没有植入代码到cpp里看起来还是不那么靠谱。正好HJ醒了,但是他不记得VMatrix里怎么弄的测试代码了,想来也不是负责这个部分的。
退而求其次,就植入代码到cpp里测试吧。
这样就有了参考:https://stackoverflow.com/questions/282194/how-to-get-memory-usage-under-windows-in-c
=>https://msdn.microsoft.com/en-us/library/windows/desktop/ms682050(v=vs.85).aspx
代码:
#include <windows.h> #include <stdio.h> #include <psapi.h> #include <unistd.h> // To ensure correct resolution of symbols, add Psapi.lib to TARGETLIBS // and compile with -DPSAPI_VERSION=1 const int _PER_SIZE = 1024 * 1024;// bytes->MB int X[1000][1000]; int main( void ) { // Get the list of process identifiers. // DWORD aProcesses[1024], cbNeeded, cProcesses; // unsigned int i;// Calculate how many process identifiers were returned. // cProcesses = cbNeeded / sizeof(DWORD); for (int i = 0; i < 1000; i ++) { for (int j = 0; j < 1000; j++) { X[i][j] = i * j + 3; } } // Get the handle HANDLE hProcess = GetCurrentProcess(); PROCESS_MEMORY_COUNTERS pmc; // Print the memory usage for current process for (int i = 0; i < 3; i++) { if ( GetProcessMemoryInfo( hProcess, &pmc, sizeof(pmc))) { printf("No.%d ", i + 1); printf( " PageFaultCount: 0x%08X ", pmc.PageFaultCount ); printf( " PeakWorkingSetSize: 0x%08X ", pmc.PeakWorkingSetSize ); // Most close to the true memory used printf( " WorkingSetSize: 0x%08X ", pmc.WorkingSetSize ); printf( " WorkingSetSize in MB: %f ", (double)pmc.WorkingSetSize / _PER_SIZE); sleep(1); } } CloseHandle( hProcess ); // PrintMemoryInfo(cur); return 0; }
这一个代码通过句柄返回信息,跟实际占用内存最接近的是WorkingsetSize。
问题是它不能统计一段时间内用到的最大内存,所以跟OJ的要求还是有出入的。也就是说到最后我没有实现exe单文件的测试代码,也没有办法获得最大memory使用,甚至于代码还不能用在linux上。囧。就先这样吧。其实代码的需求一般只有统计时间而已。
好的,统计时间的代码:
#include<ctime> #include<iostream> using namespace std; int main() { clock_t startCTime , endCTime; startCTime = clock(); //clock函数返回CPU时钟计时单元(clock tick)数,还有一个常量表示一秒钟有多少个时钟计时单元,可以用clock()/CLOCKS_PER_SEC来求取时间 // your code endCTime = clock(); cout << double(endCTime-startCTime)/CLOCKS_PER_SEC << "s" << endl; return 0; }