线上上课为我的 csgo 提供了很多时间。一打 go 发现作业就写不完了。特此想方设法用C语言写出一个统计程序运行时间的程序,这样就非常清楚我什么时候开始打 go,打了多久的 go。
没学过多线程,pthread 的代码是看着百度照样子打下来的。这个程序可以统计一个程序从开始运行到结束一共有多久时间,并把程序名、开始时间、结束时间、间隔时间输出到 csv 文件中。线程数可以自己定义。错误肯定很多,欢迎指出。但是程序能跑就行哈哈哈。
发现我的 C-Free 没有 pthread.h,我也不会配置,所以只好用原始的方法来写。编辑器是 VS code,编译器是 Mingw。用 gcc 命令手动链接编译。
两个配置文件要在文件的程序的根目录手动建立:FilePath.txt 里面装的是 csv文件的绝对路径,还有一个 gamelist.txt 里面放的是要统计的程序。
代码如下:
#include<stdio.h>
#include<stdbool.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<windows.h>
#include<tlhelp32.h>
#include<pthread.h>
#include<time.h>
#define thread_amount 4
char arry[20];
char GameProcess[100][300];
int ProcessState[100];
int GameNO=0;
struct ExGame{
char name[300];
int state;
}ExGame[10];
struct working_pthread{
int state;
int number;
char Gamename[400];
}thread[thread_amount];
int GetGameProcessList();
int GetSystemProcess(char (*)[300]);
void *test(void *);
void TimeTransfer(time_t Timestamp,int type,char Transfer_Time[]);
int main()
{
char systemProcess[1000][300];
int ProcessAmount,GameAmount,result[2];
int i=0,j=0,k=0,flag=0;
pthread_t tid[thread_amount];
thread[0].state=0;
thread[1].state=0;
HWND hwnd=GetForegroundWindow();// 隐藏控制台窗口
ShowWindow(hwnd,SW_HIDE);// 隐藏控制台窗口
//printf("Main process is running\n");
while(1)
{
//printf("in while\n");
i=j=k=0;
GameAmount=GetGameProcessList();
ProcessAmount=GetSystemProcess(systemProcess);
//printf("[%s] [%s]\n",GameProcess[0],GameProcess[1]);
//printf("-----------\n");
for(i=0;i<ProcessAmount;i++)
{
//printf("in 1 for\n");
for(j=0;j<GameAmount;j++)
{
//printf("in 2 for\n");
result[0]=strcmp(GameProcess[j],systemProcess[i]);
//printf("[%s][%s][%d]\n",GameProcess[j],systemProcess[i],result[0]);
if(result[0]==0)
{
//printf("in 1 if\n");
for(k=0;k<thread_amount;k++)
{
//printf("in 3 for\n");
result[1]=strcmp(thread[k].Gamename,GameProcess[j]);
//printf("%d %d %d\n",thread[0].state,thread[1].state,result[1]);
//printf("-------\n%d\n-------\n",thread_amount);
if(result[1]==0)
{
//printf("in 2 if\n");
break;
}
if(thread[k].state==0)
{
//printf("in 3 if\n");
//printf("Starting pthread %d\n",k);
strcpy(thread[k].Gamename,GameProcess[j]);
pthread_create(&tid[k],NULL,test,&thread[k]);
thread[k].state=1;
thread[k].number=k;
break;
}
}
}
}
}
//printf("k=%d",k);
if(GameNO==0)
{
memset(&ExGame,0,sizeof(ExGame));
//for(i=0;i<k;i++)
//printf("%s %d\n",ExGame[i].name,ExGame[i].state);
//printf("Empty\n");
}else{
for(i=0;i<GameNO;i++)
;
//printf("%s %d %d\n",ExGame[i].name,i,GameNO);
}
//pthread_create(&tid[0],NULL,test,&k);
Sleep(1000);
//system("cls");
}
}
int GetGameProcessList()
{
int NO=0,i=0;
FILE *ProcessList;
ProcessList = fopen(".\\GameList.txt","r");
//判断进程列表文件是否打开
if(ProcessList==NULL)
{
//printf("Failed to open process file.");
MessageBox(NULL,"Failed to open process file.","Notice",MB_OK);
exit(1);
}
while((fscanf(ProcessList,"%s",GameProcess[NO]))!=EOF)
NO++;
fclose(ProcessList);
return(NO);
}
int GetSystemProcess(char processName[][300])
{
int i=0,j=0;
PROCESSENTRY32 currentProcess;
currentProcess.dwSize = sizeof(currentProcess);
HANDLE hProcess = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
if (hProcess == INVALID_HANDLE_VALUE)
{
//printf("Failed to create process snapshot!\n");
MessageBox(NULL,"Failed to create process snapshot!\n","Notice",MB_OK);
}
bool bMore=Process32First(hProcess,¤tProcess);
while(bMore)
{
//printf("%s\n",currentProcess.szExeFile);
bMore=Process32Next(hProcess,¤tProcess);
memcpy(processName[i],currentProcess.szExeFile,sizeof(currentProcess.szExeFile));
i++;
}
CloseHandle(hProcess);
return(i);
}
void *test(void *arryT)
{
int i,processAmount,flag;
int sec,min;
char message1[500];
char FilePath[300];
char systemProcess[1000][300];
char transStartTime[50];
char transEndTime[50];
struct working_pthread *arry;
FILE *fp;
FILE *PathFile;
arry=(struct working_pthread*)arryT;
PathFile=fopen(".\\PathFile.txt","r");
fscanf(PathFile,"%s",FilePath);
fclose(PathFile);
//printf("%s",FilePath);
time_t RawstartTime;
time_t RawendTime;
time(&RawstartTime);
TimeTransfer(RawstartTime,1,transStartTime);
//printf("Thread %d is running.\n",(*arry).number);
//printf("Process %s from pthread %d is running at %s.\n",(*arry).Gamename,(*arry).number,transStartTime);
while(1)
{
//printf("Process %s from pthread %d is running at %s.\n",(*arry).Gamename,(*arry).number,transStartTime);
flag=0;
processAmount=GetSystemProcess(systemProcess);
//printf("First process is %s\n",systemProcess[10]);
for(i=0;i<processAmount;i++)
{
if(strcmp((*arry).Gamename,systemProcess[i])==0)
{
flag=1;
break;
}
}
if(flag==1)
{
;
}else{
time(&RawendTime);
TimeTransfer(RawendTime,1,transEndTime);
sec=RawendTime - RawstartTime;
min=(sec - sec%60)/60;
sec=sec%60;
sprintf(message1,"%s 打开 %s\n%s 结束 %s\n运行时间 %d分%d秒\n",transStartTime,(*arry).Gamename,transEndTime,(*arry).Gamename,min,sec);
//printf("Process %s has been killed at %s lasted for %d mins %d secs..\n",(*arry).Gamename,transEndTime,min,sec);
fp=fopen(FilePath,"a+");
fprintf(fp,"%s,%s,%s,%d分%d秒\n",(*arry).Gamename,transStartTime,transEndTime,min,sec);
fclose(fp);
MessageBox(NULL,message1,"时长提示",MB_OK);
//printf("%s",message1);
//printf("%s 打开 %s\n%s 结束 %s\n运行时间 %d 分%d 秒",transStartTime,(*arry).Gamename,transEndTime,(*arry).Gamename,min,sec);
thread[(*arry).number].state=0;
memset(thread[(*arry).number].Gamename,'\0',sizeof(thread[(*arry).number].Gamename));
pthread_exit(NULL);
}
Sleep(1000);
}
}
void TimeTransfer(time_t Timestamp,int type,char Transfer_Time[])
{
char Time1[40];
struct tm* timeinfo;
if(type==1)
{
timeinfo=localtime(&Timestamp);
strftime(Time1,sizeof(Time1),"%Y年%m月%d日%H时%M分%S秒",timeinfo);
}
strcpy(Transfer_Time,Time1);
}
有些废代码在里面,待我抽出时间来好好改改,加点注释。
这是我的 GameList.txt
这是 FilePath.txt
对了,csv文件也要提前手动建立好。文件名一定要和程序里一样,该大写大写,该小写小写。
用了个API(也是百度的),隐藏了控制台窗口。
统计过的csv文件:
NND,16号打了四个小时的GO,怪不得作业没时间写。