设计一个程序,每秒统计一次当前系统的进程状况。

本文介绍了一个使用VS2019实现的程序,该程序能够实时监控系统进程,每秒更新一次进程状态,按内存使用量排序并显示当前运行的进程。同时,程序会跟踪已结束的进程,记录其结束时间和持续时间。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

设计一个程序,每秒统计一次当前系统的进程状况,并按照内存使用自多到少排序打印输出相关信息。对已经结束的进程,另外给出一个列表,并显示该进程的结束时间和持续时间。(一个进程既可被结束,也可以过一段时间后再被运行。)

用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, &currentProcess); //获取第一个进程信息
	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, &currentProcess);                                                //遍历下一个
		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;
}

 

评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值