系统进程

发布时间 2023-12-27 10:57:49作者: 小菜碟子

算法思想:读取当前进程Current,并对其进行冒泡排序。对Total中每一个节点进行搜索,如果在Current中说明未结束进程更新持续时间,如果不在Current中,说明已结束更新Finished的endTime和持续时间。对Current中每个节点搜索,在Total中并且Finished 的endTime不等于0,则重新启用该进程更新endTime和持续时间,如果在Total中,但endTime等于零,则还在进行不做操作,如果不在Total中,则是新加入的进程更新Total和Finished.对finish的进行排序,打印(endTime不等于0的为已结束进程)

主要/核心函数分析:调整结束时间及持续时间UpdateTime(Total, Current, Finished);调整重新调用的程序及新调用的程序UpdateProgarm(Total, Current, Finished);在前面算法思想中已经说明。

测试数据:本电脑

运行结果:运行前打开QQ,运行停顿时我用进程管理系统结束QQ的所有进程来查看正确性。每次与系统进程进行比较。

时间复杂度:每一秒更新的时间复杂度是O(2*Total*Current+Finished*Finished+Total*Total+2*Current+Finished) 

心得体会:学会了单链表和双链表的区别与使用,同时也学会了如何获取系统当前进程。以及合适的中间媒介来完成所需工作,就像这题的Total链表就是媒介用来联系Current和Finished。还对链表排序有了更深层次的理解

  1 #undef UNICODE
  2 #undef _UNICODE
  3 #include<iostream>
  4 #include<iomanip>
  5 #include<cstdio>
  6 #include<windows.h>
  7 #include<TLHELP32.h>
  8 #include<iomanip>
  9 #include<string>
 10 #include"Psapi.h"
 11 #include<ctime>
 12 #pragma comment(lib,"Psapi.lib")
 13 using namespace std;
 14 
 15 typedef struct DLNode 
 16 {
 17     char name[100];//进程名
 18     int duration;//持续时间
 19     int endTime;//结束时间
 20     DLNode* prior, * next;
 21 }DLNode, * DLinkList;//双向链表
 22 
 23 typedef struct SLNode 
 24 {
 25     char name[100];//进程名
 26     int duration;//持续时间
 27     int memory;//内存使用情况
 28     SLNode* next;
 29 }SLNode, * SLinkList;//单向链表
 30 
 31 //获取内存
 32 int GetMemoryInfo(DWORD processID)
 33 {
 34     //API
 35     HANDLE hProcess;
 36     PROCESS_MEMORY_COUNTERS pmc;
 37     hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, processID);
 38     if (hProcess == NULL)
 39         return 0;
 40 
 41     //GetProcessMemoryInfo()用于获取内存的使用情况
 42     if (GetProcessMemoryInfo(hProcess, &pmc, sizeof(pmc)))
 43     {
 44         CloseHandle(hProcess);
 45 
 46         //pmc.WorkingSetSize就是程序在当前代码处的内存使用量
 47         return pmc.WorkingSetSize;
 48     }
 49 }
 50 
 51 //创建当前进程链表
 52 int CreateList(SLinkList& S) 
 53 {
 54     //头结点
 55     S = (SLinkList)malloc(sizeof(SLNode));
 56     S->duration = 0;
 57     S->memory = 0;
 58     S->next = NULL;
 59 
 60     SLinkList Fakehead = S, newnode;
 61 
 62     //存放进程信息的结构体
 63     PROCESSENTRY32 temp;
 64     temp.dwSize = sizeof(temp);
 65 
 66     //获取系统内的所有进程
 67     HANDLE hProcessSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
 68     if (INVALID_HANDLE_VALUE == hProcessSnapshot)
 69     {
 70         printf("未获得进程!\n");
 71         return 0;
 72     }
 73 
 74     //获取进程
 75     BOOL bMore = Process32First(hProcessSnapshot, &temp);
 76     while (bMore) 
 77     {
 78         //获得当前进程的内存量
 79         int judge = GetMemoryInfo(temp.th32ProcessID);
 80         if (judge) 
 81         {
 82             //新进程的内容赋给新结点,接在双向链表最后
 83             newnode = (SLinkList)malloc(sizeof(SLNode));
 84             newnode->memory = judge / 1024;
 85             strcpy_s(newnode->name, temp.szExeFile);
 86             newnode->duration = 0;
 87             Fakehead->next = newnode;
 88             newnode->next = NULL;
 89             Fakehead = newnode;
 90         }
 91         bMore = Process32Next(hProcessSnapshot, &temp);
 92     }
 93     //清除hProcess句柄
 94     CloseHandle(hProcessSnapshot);
 95     return 1;
 96 }
 97 
 98 //根据PID,在储存结束时间的链表中查找该进程
 99 void LocateOverList(DLinkList& D, char* key, DLinkList& p)
100 {
101     //在已结束进程中查找
102     p = D->next;
103     while (p != D)
104     {
105         if (strcmp(p->name, key)==0)
106             return;
107         p = p->next;
108     }
109     return ;
110 }
111 
112 //创建已结束进程链表
113 int CreateEndedList(DLinkList& Finished, SLinkList Total)
114 {
115     //把总进程链表所有内容赋给记录已结束进程链表
116     Finished = (DLinkList)malloc(sizeof(DLNode));
117     Finished->duration = 0;//总时间
118     Finished->endTime = 0;//结束时间
119     Finished->next = Finished;
120     Finished->prior = Finished;
121     SLinkList  cur_S = Total->next;
122     DLinkList cur_D = Finished, newnode;
123     while (cur_S) 
124     {
125         newnode = (DLinkList)malloc(sizeof(DLNode));
126         strcpy_s(newnode->name, strlen(cur_S->name) + 1, cur_S->name);
127         newnode->duration = 0;
128         newnode->endTime = 0;
129 
130         newnode->next = cur_D->next;
131         cur_D->next->prior = newnode;
132         cur_D->next = newnode;
133         newnode->prior = cur_D;
134         
135         cur_D = cur_D->next;
136         cur_S = cur_S->next;
137     }
138     return 1;
139 }
140 
141 //按持续时间给进程排序
142 int SortDList(DLinkList& D) 
143 {
144     //统计结点数目
145     int statisticNum = 0;
146     DLinkList statistic = D->next;
147     while (statistic!=D) 
148     {
149         statisticNum++;
150         statistic = statistic->next;
151     }
152 
153     //冒泡排序
154     DLinkList q = D->next;
155     DLinkList t = (DLinkList)malloc(sizeof(DLNode));
156     //标记排序是否发生交换
157     //若不发生交换
158     //则排序完成
159     int flag = 1;
160 
161     while (flag == 1 && statisticNum-1> 0)
162     {
163         q = D->next;
164         //若没有发生交换
165         //flag为0,则不会发生下一趟排序
166         flag = 0;
167         for (int i = 1; i < statisticNum; i++)
168         {
169             if (q->duration > q->next->duration)
170             {
171                 flag = 1;
172                 strcpy_s(t->name, strlen(q->name) + 1, q->name);
173                 t->endTime = q->endTime;
174                 t->duration = q->duration;
175                 strcpy_s(q->name, strlen(q->next->name) + 1, q->next->name);
176                 q->endTime = q->next->endTime;
177                 q->duration = q->next->duration;
178                 strcpy_s(q->next->name, strlen(t->name) + 1, t->name);
179                 q->next->endTime = t->endTime;
180                 q->next->duration = t->duration;
181             }
182             q = q->next;
183         }
184         statisticNum--;
185     }
186     free(t);
187     return 1;
188 }
189 
190 //按照内存大小排序
191 int SortSList(SLinkList& S) 
192 {
193     //记录结点数目
194     int statisticNum = 0;
195     SLinkList statistic = S->next;
196     while (statistic) 
197     {
198         statisticNum++;
199         statistic = statistic->next;
200     }
201 
202     //冒泡排序
203     SLinkList q = S->next;
204     SLinkList t = (SLinkList)malloc(sizeof(SLNode));
205     //标记排序是否发生交换
206     //若不发生交换
207     //则排序完成
208     int flag = 1;
209 
210     while (flag == 1 && statisticNum - 1 > 0)
211     {
212         q = S->next;
213         //若没有发生交换
214         //flag为0,则不会发生下一趟排序
215         flag = 0;
216         for (int i = 1; i < statisticNum; i++)
217         {
218             if (q->memory < q->next->memory)
219             {
220                 flag = 1;
221                 strcpy_s(t->name, strlen(q->name) + 1, q->name);
222                 t->memory = q->memory;
223                 t->duration = q->duration;
224                 strcpy_s(q->name, strlen(q->next->name) + 1, q->next->name);
225                 q->memory = q->next->memory;
226                 q->duration = q->next->duration;
227                 strcpy_s(q->next->name, strlen(t->name) + 1, t->name);
228                 q->next->memory = t->memory;
229                 q->next->duration = t->duration;
230             }
231             q = q->next;
232         }
233         statisticNum--;
234     }
235     free(t);
236     return 1;
237 }
238 
239 //统计已结束进程
240 int UpdateTime(SLinkList& Total, SLinkList& Current, DLinkList& Finished)
241 {
242     //判断有无找到未结束进程
243     int judge;
244 
245     DLinkList p_Finished = Finished->next;
246     SLinkList p_Total = Total->next, p_Current;
247 
248     //头结点用来记录调试时间
249     Finished->duration += 1;
250 
251     while (p_Total)
252     {
253         //重置为1
254         judge = 1;
255 
256         //寻找有无未结束进程
257         p_Current = Current->next;
258         while (p_Current)
259         {
260             //该进程未结束
261             if (strcmp(p_Current->name,p_Total->name)==0)
262             {
263                 //找到,置为0
264                 judge = 0;
265                 break;
266             }
267             p_Current = p_Current->next;
268         }
269 
270         //进程已结束
271         if (judge)
272         {
273             //获取该结束进程在已结束进程链表的位置
274             //更新结束时间
275             LocateOverList(Finished, p_Total->name,p_Finished);
276 
277             //如果结束时间为0,更新结束时间
278             //如果结束时间不为0,更新结束的持续时间
279             if (p_Finished->endTime == 0)
280                 p_Finished->endTime = Finished->duration;
281             else
282                 p_Finished->duration += 1;
283         }
284 
285         //进程未结束
286         //更新当前进程的运行的持续时间
287         else 
288         {
289             p_Total->duration += 1;
290             p_Current->duration = p_Total->duration;
291         }
292 
293         p_Total = p_Total->next;
294     }
295     return 1;
296 }
297 
298 //刷新后更新进程
299 int UpdateProgarm(SLinkList& Total, SLinkList Current, DLinkList& Finished)
300 {
301     //判断有无找到新进程
302     int judge;
303 
304     DLinkList p_Finished = Finished->next, q_Finished = Finished->next, temp_finished ;
305 
306     SLinkList p_Total = Total->next, p_Current = Current->next, q_Total = Total->next, temp_Total;
307 
308     //遍历当前进程表
309     while (p_Current) 
310     {
311         judge = 1;
312 
313         p_Total = Total->next;
314         while (p_Total) 
315         {
316             //该进程已在进程表中
317             if (strcmp(p_Current->name,p_Total->name)==0)
318             {
319                 judge = 0;
320                 break;
321             }
322             p_Total = p_Total->next;
323         }
324 
325         //进程不在total中,将其添加
326         if (judge)
327         {
328             while (q_Total->next)
329             {
330                 q_Total = q_Total->next;
331             }
332             temp_Total = (SLinkList)malloc(sizeof(SLNode));
333             temp_Total->memory = p_Current->memory;
334             temp_Total->duration = 0;
335             strcpy_s(temp_Total->name, p_Current->name);
336             q_Total->next = temp_Total;
337             temp_Total->next = NULL;
338 
339             while (q_Finished->next != Finished)
340             {
341                 q_Finished = q_Finished->next;
342             }
343             temp_finished = (DLinkList)malloc(sizeof(DLNode));
344             temp_finished->duration = 0;
345             temp_finished->endTime = 0;
346             strcpy_s(temp_finished->name, p_Current->name);
347             q_Finished->next->prior = temp_finished;
348             temp_finished->next = q_Finished->next;
349             q_Finished->next = temp_finished;
350             temp_finished->prior = q_Finished;
351         }
352         else 
353         {
354             p_Finished = Finished->next;
355             while (p_Finished!=Finished)
356             {
357                 if (strcmp(p_Current->name ,p_Finished->name)==0 && p_Finished->endTime != 0)
358                 {
359                     //重新启用进程
360                     p_Finished->endTime = 0;
361 
362                     p_Current->duration = p_Total->duration = 0;
363                     break;
364                 }
365                 p_Finished = p_Finished->next;
366             }
367         }
368         p_Current = p_Current->next;
369     }
370     return 1;
371 }
372 
373 //显示当前进程
374 void ShowArray_D(SLinkList SL, DLinkList DL) 
375 {
376     cout.setf(ios::left);
377     cout << setw(20) << "当前系统进程名" << '    ';
378     cout.setf(ios::right, ios::left);
379     cout << '    ' << setw(17) << "内存使用情况" << '    ' << "持续时间" << '    ' << setw(20) << endl;
380     cout << "----------------------------------------------------------------" << endl;
381 
382     DLinkList p = DL->next;
383     SLinkList s = SL->next;
384 
385     //打印当前进程链表的内容
386     while (s) 
387     {
388         char* nameSave = s->name;
389         for (int i = 0; i < 20; i++) 
390         {
391             cout << nameSave[i];
392             if (nameSave[i] == '\0') 
393             {
394                 for (int j = i; j < 20; j++) 
395                     cout << " ";
396                 break;
397             }
398         }
399 
400         cout.setf(ios::left);
401         cout << '    ';
402 
403         cout.setf(ios::right, ios::left);
404         cout << '    ' << setw(15) << s->memory << "KB";
405         if (s->duration < 60)
406             cout << '    ' << s->duration << "s" << endl;
407         if (s->duration >= 60)
408             cout << '    ' << s->duration / 60 << "m  " << s->duration % 60 << "s" << endl;
409 
410         s = s->next;
411     }
412     cout << endl;
413 
414     if (p!=DL) 
415     {
416         cout.setf(ios::left);
417         cout << setw(20) << "已结束进程名" << '    ';
418         cout.setf(ios::right, ios::left);
419         cout << '    ' << setw(17) << "持续时间" << '    ' << "结束时间" << '    ' << setw(20) << endl;
420         cout << "----------------------------------------------------------------" << endl;
421     }
422 
423     //当链表未结束
424     //已结束进程链表的结点的endTime值不为0,打印
425     while (p!=DL)
426     {
427         if (p->endTime != 0)
428         {
429             char* nameSave1 = p->name;
430             for (int i = 0; i < 20; i++)
431             {
432                 cout << nameSave1[i];
433                 if (nameSave1[i] == '\0')
434                 {
435                     for (int j = i; j < 20; j++)
436                         cout << " ";
437                     break;
438                 }
439             }
440 
441             cout.setf(ios::left);
442             cout << '\t';
443 
444             cout.setf(ios::right, ios::left);
445             if (p->duration < 60)
446                 cout << '    ' << setw(15) << p->duration << "s";
447             if (p->duration >= 60)
448                 cout << '    ' << setw(12) << p->duration / 60 << "m  " << p->duration % 60 << "s";
449 
450 
451             cout.setf(ios::left, ios::right);
452 
453             if (p->endTime < 60)
454                 cout << '    ' << p->endTime << "s" << endl;
455             if (p->endTime >= 60)
456                 cout << '    ' << p->endTime / 60 << "m  " << p->endTime % 60 << "s" << endl;
457         }
458 
459         p = p->next;
460     }
461 }
462 
463 int main() 
464 {
465     //Total为总进程表,cuttent为当前进程表
466     SLinkList Total;
467     SLinkList Current;
468     //Finished中存储已结束进程
469     DLinkList Finished;
470     //创建该程序执行时得到的最初的进程表,用于与当前进程比对,来获取已结束进程
471     CreateList(Total);
472     //创建结束进程表
473     CreateEndedList(Finished, Total);
474     //排序
475     SortSList(Total);
476     //打印
477     ShowArray_D(Total, Finished);
478 
479     int times = 5;//次数
480 
481     while (times) 
482     {
483         Sleep(500);
484         //清屏
485         system("cls");
486         //获取当前进程表
487         CreateList(Current);
488         //排序
489         SortSList(Current);
490         //调整结束时间及持续时间
491         UpdateTime(Total, Current, Finished);
492         //调整重新调用的程序及新调用的程序
493         UpdateProgarm(Total, Current, Finished);
494         //排序
495         SortDList(Finished);
496         //打印
497         ShowArray_D(Current, Finished);
498         times--;
499         //暂停一下
500         system("pause");
501     }
502     system("pause");
503     return 0;
504 }