设计一个程序,每秒统计一次当前系统的进程状况,并按照内存使用自多到少排序打印输出相关信息。对已经结束的进程,另外给出一个列表,并显示该进程的结束时间和持续时间。(一个进程既可被结束,也可以过一段时间后再被运行。)
用VS2019实现
问题是获取当前系统的进程状况,并对进程进行维护,另外显示一个已结束进程表,对其中进程进行维护。
获取当前系统的进程状况,首先,通过进程快照得到进程,通过Process32First()函数获取第一个进程信息,通过Process32Next()循环获取下一个进程信息,使用API函数GetProcessMemoryInfo()来获取内存的使用情况,进程信息储存在类型PROCESSENTRY32 的对象currentProcess中, currentProcess.th32ProcessID,currentProcess.szExeFile,上述两项分别为进程PID和进程名。
根据进程的进程名,内存大小,PID来建立初始链表,建立两个空链表,一个为已结束进程表,已结束进程表中增设持续时间和结束时间的变量,另一个为当前进程表。 通过Sleep()函数,每过1秒,获取一次当前进程,和初始进程表比较,如果出现新进程,则添加进初始进程表,如果初始进程表中某进程在当前进程表中未出现,说明该进程结束,将其加入已结束进程表,并记录持续时间和结束时间。
显示,通同过任意排序算法(这里选用起泡排序)按照内存大小将当前进程表中的进程排序,而后输出,按照结束时间,将已结束进程表中的进程排序并输出。
#pragma comment(lib, "Psapi.lib")//外部链接
#include <windows.h>
#include <tlhelp32.h>//进程快照函数头文件
#include <stdio.h>
#include <psapi.h>
#define INTERVAL 5000//每5秒统计一次
typedef int Status;
typedef struct DLNode
{
int PID;
int PMemory;
char PName[100];
DLNode* pre, * next;
}DLNode, *DLinkList;//存储当前进程
typedef struct SLNode
{
int PID;
char PName[100];
int endT; //进程结束时间endT == 0说明进程未结束
int Duration;//进程持续时间
SLNode* next;
}SLNode, * SLinkList;//存储结束进程
Status SortDList(DLinkList& L);//按内存大小给进程排序
Status SortSList(SLinkList& S);//按照结束时间排序
Status CreateList(DLinkList& L);//创建当前进程链表
Status CreateOverList(SLinkList& S, DLinkList L);//创建已结束进程链表
Status OverTime(DLinkList L, DLinkList currentL, SLinkList& S);//统计已结束进程
Status Startprogarm(DLinkList &L, DLinkList currentL, SLinkList& S);//统计新进程
SLinkList LocateOverList(SLinkList& S, const int PID);//根据进程名,在储存结束时间的链表中查找该进程
void Showarray_D(DLinkList L, SLinkList S);//显示当前进程情况
void Showarray_S(SLinkList S);//显示已结束进程
int main()
{
SLinkList S;//S中存储已结束进程
DLinkList L, currentL;//L为总进程表,cuttentL为当前进程表
CreateList(L);//创建该程序执行时得到的最初的进程表,用于与当前进程比对,来获取已结束进程
CreateOverList(S, L);//创建结束进程表,
SortDList(L);//排序
Showarray_D(L, S);
while (1)
{
Sleep(INTERVAL);//每过INTERVALms获取一次当前进程
system("cls");
S->Duration += INTERVAL/1000;//总持续时间增加
CreateList(currentL);//获取当前进程表
SortDList(currentL);
OverTime(L, currentL, S);//调整结束时间及持续时间
SortSList(S);
Startprogarm(L, currentL, S);//调整重新调用的程序及新调用的程序
printf("Running process:\n");
Showarray_D(currentL, S);
printf("Closed process:\n");
Showarray_S(S);
}
system("pause");
}
Status Startprogarm(DLinkList& L, DLinkList currentL, SLinkList& S)
{
int judge = 1, i = 1;
SLinkList p_S = S->next, q_S = S->next,temp_S = (SLinkList)malloc(sizeof(SLNode));
DLinkList p_L = L->next, p_currentL = currentL->next, q_L = L->next, temp_L = (DLinkList)malloc(sizeof(DLNode));
while (p_currentL)//遍历当前进程表
{
i=1;
judge = 1;
p_L = L->next;
while (p_L)
{
if (p_currentL->PID == p_L->PID)//该进程已在进程表L中
{
judge = 0;
break;
}
p_L = p_L->next;
}
p_S = S->next;
while (p_S && i <= S->PID)
{
if (strcmp(p_currentL->PName, p_S->PName) == 0)
{
p_S->endT = 0;//重新启用进程
break;
}
i++;
p_S = p_S->next;
}
if (judge)//进程不在L中,将其添加如L,S表中
{
while (q_L->next)
{
q_L = q_L->next;
}
temp_L = (DLinkList)malloc(sizeof(DLNode));
temp_L->PID = p_currentL->PID;
temp_L->PMemory = p_currentL->PMemory;
strcpy_s(temp_L->PName, p_currentL->PName);
q_L->next = temp_L;
temp_L->next = NULL;
temp_L->pre = q_L->next;
L->PMemory++;
while (q_S->next)
{
q_S = q_S->next;
}
temp_S = (SLinkList)malloc(sizeof(SLNode));
temp_S->PID = p_currentL->PID;
temp_S->Duration = 0;
temp_S->endT = 0;
strcpy_s(temp_S->PName, p_currentL->PName);
q_S->next = temp_S;
temp_S->next = NULL;
S->endT++;
}
p_currentL = p_currentL->next;
}
return 1;
}
Status SortSList(SLinkList& S)//按照结束时间排序
{
int i = 1, j = 1;
SLinkList q, t = (SLinkList)malloc(sizeof(SLNode));
for (i = 1; i <= S->endT; i++)//起泡排序
{
for (q = S->next, j = 1; q->next != NULL && j <= S->endT - i; q = q->next, j++)
{
if (q->endT < q->next->endT)//根据结束时间从大到小排序
{
t->Duration = q -> Duration;
t->endT = q->endT;
t->PID = q->PID;
strcpy_s(t->PName, q->PName);
q->Duration = q->next->Duration;
q->endT = q->next->endT;
q->PID = q->next->PID;
strcpy_s(q->PName, q->next->PName);
q->next->Duration = t-> Duration;
q->next->endT = t->endT;
q->next->PID = t->PID;
strcpy_s(q->next->PName, t->PName);
}
}
}
return 1;
}
void Showarray_S(SLinkList S)
{
SLinkList p = S->next;
while (p)
{
if (p->endT != 0)
{
printf("PName= %s Duration=%d EndT=%d\n", p->PName, p->Duration, p->endT);
}
p = p->next;
}
}
SLinkList LocateOverList(SLinkList& S, const int PID)//在已结束进程中查找进程编号为PID的进程
{
SLinkList p = S->next;
while (p)
{
if (PID == p->PID)
return p;
p = p->next;
}
return NULL;
}
Status CreateOverList(SLinkList& S, DLinkList L)
{
S= (SLinkList)malloc(sizeof(SLNode));
S->PID = 0;//总结束的进程的数量
S->Duration = 0;//总时间
S->endT = L->PMemory;//总进程的数量
DLinkList p_L = L->next;
SLinkList p_S = S, q_S = (SLinkList)malloc(sizeof(SLNode));
while (p_L)
{
q_S = (SLinkList)malloc(sizeof(SLNode));
strcpy_s(q_S->PName, p_L->PName);
q_S->Duration = 0;
q_S->endT = 0;
q_S->PID = p_L->PID;
p_S->next = q_S;
p_S = q_S;
p_L = p_L->next;
}
q_S->next = NULL;
return 1;
}
Status OverTime(DLinkList L, DLinkList currentL, SLinkList& S)//统计结束进程
{
int judge = 1;
SLinkList p_S = S->next;
DLinkList p_L = L->next, p_currentL = currentL->next;
while (p_L)
{
judge = 1;
p_currentL = currentL->next;
while (p_currentL)
{
if (p_currentL->PID == p_L->PID)//该进程未结束
{
judge = 0;
break;
}
p_currentL = p_currentL->next;
}
if (judge)
{
p_S = LocateOverList(S, p_L->PID);
if (p_S->endT == 0)//代表该进程是新结束的进程
{
p_S->Duration += INTERVAL / 1000;
p_S->endT = S->Duration;
S->PID++;
}
}
else
{
p_S = LocateOverList(S, p_L->PID);
p_S->Duration += INTERVAL/1000;
}
p_L = p_L->next;
}
return 1;
}
Status CreateList(DLinkList& L)//建立储存进程的循环链表
{
L = (DLinkList)malloc(sizeof(DLNode));
DLinkList p = L, q = (DLinkList)malloc(sizeof(DLNode));
HANDLE handle = GetCurrentProcess();
PROCESS_MEMORY_COUNTERS pmc;
int countProcess = 0, countNoPower = 0;//当前进程数量和没有权限访问的进程数量
PROCESSENTRY32 currentProcess;//存放进程信息
currentProcess.dwSize = sizeof(currentProcess);
HANDLE hProcess = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);//获取系统内的所有进程
if (hProcess == INVALID_HANDLE_VALUE)
{
printf("CreateToolhelp32Snapshot()函数调用失败!\n");
return -1;
}
bool bMore = Process32First(hProcess, ¤tProcess); //获取第一个进程信息
while (bMore)
{
int judge = 1;
if (!(handle = OpenProcess(PROCESS_ALL_ACCESS, 0, currentProcess.th32ProcessID)))//令handle为编号为PID进程的权柄
{
countNoPower++;
judge = 0;
}//有很多进程openprocess函数无权限访问,需自行提权
GetProcessMemoryInfo(handle, &pmc, sizeof(pmc));//函数,从某进程中得到内存大小
if (judge)
{
q = (DLinkList)malloc(sizeof(DLNode));
if (!q)exit(-2);
q->PMemory = pmc.WorkingSetSize / 1024;
q -> PID = currentProcess.th32ProcessID;
strcpy_s(q->PName, currentProcess.szExeFile);
p->next = q;
q->pre = p;
p = q;
}
bMore = Process32Next(hProcess, ¤tProcess); //遍历下一个
countProcess++;
}
CloseHandle(hProcess); //清除hProcess句柄
L->PMemory = countProcess - countNoPower;//头节点储存有权限访问的程序数
q->next = NULL;
return 1;
}
void Showarray_D(DLinkList L, SLinkList S)
{
int i = 0;
SLinkList q = S->next;
DLinkList p = L->next;
while (p != NULL)
{
q = LocateOverList(S, p->PID);
if (q)
{
printf("PMemory=%7uKB PName= %s Duration=%d\n", p->PMemory, p->PName,q->Duration);
}
p = p->next;
}
}
Status SortDList(DLinkList& L)//按内存大小给进程排序
{
int i = 1, j = 1;
DLinkList q, t = (DLinkList)malloc(sizeof(DLNode));
for (i = 1; i <= L->PMemory; i++)//起泡排序
{
for (q = L->next, j = 1; q->next != NULL && j <= L->PMemory - i; q = q->next, j++)
{
if (q->PMemory < q->next->PMemory)//根据内存从大到小排序
{
t->PID = q -> PID;
t->PMemory = q->PMemory;
strcpy_s(t->PName, q->PName);
q->PID = q->next->PID;
q->PMemory = q->next->PMemory;
strcpy_s(q->PName, q->next->PName);
q->next->PID = t->PID;
q->next->PMemory = t->PMemory;
strcpy_s(q->next->PName, t->PName);
}
}
}
return 1;
}