操作系统之Windows 进程管理中的创建子进程

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/rothschild666/article/details/95492647

创建子进程:本实验显示了创建子进程的基本框架。该程序只是再一次地启动自身,显示它的系统进程 ID和它在进程列表中的位置。

步骤 1:创建一个“Win32 Consol Application”工程,然后可复制下面中的程序,编译成可执行文件或者使用 VC++ 6.0创建编译执行下面代码。

步骤 2:在“命令提示符”窗口运行步骤 1 中生成的可执行文件,列出运行结果。按下ctrl+alt+del,调用 windows 的任务管理器,记录进程相关的行为属性。

步骤 3:在“命令提示符”窗口加入参数重新运行生成的可执行文件,列出运行结果。按下ctrl+alt+del,调用 windows 的任务管理器,记录进程相关的行为属性。

步骤 4:修改下面中的程序,将 nClone 的定义和初始化方法按程序注释中的修改方法进行两次修改,编译成可执行文件(执行前请先保存已经完成的工作)。再按步骤 2 中的方式运行,看看结果会有什么不一样。列出行结果。从中你可以得出什么结论?说明 nClone 的作用。 变量的定义和初始化方法(位置)对程序的执行结果有影响吗?为什么?

回答:控制程序执行过程,当nClone>5时跳出循环,创建子进程结束;有,在第二次更改中,由于nClone每次都初始化为0,会陷入死循环,不断创建子进程。

代码(注意有两次修改,每次修改之后都要重新编译):

温馨提示:请注意下面的标黑的解释也就是标数字的理解顺序,仅供各位参考理解!若发现有任何错误或者有好的建议也欢迎在评论中提出!!!

#include <windows.h>
#include <iostream>
#include <stdio.h>
// 创建传递过来的进程的克隆过程并赋于其 ID 值
void StartClone(int nCloneID)
{
// 提取用于当前可执行文件的文件名
TCHAR szFilename[MAX_PATH] ;
GetModuleFileName(NULL, szFilename, MAX_PATH) ;
// 格式化用于子进程的命令行并通知其 EXE 文件名和克隆 ID
TCHAR szCmdLine[MAX_PATH];
sprintf(szCmdLine,"\"%s\" %d",szFilename,nCloneID);**//4、将传递过来自增的nCloneID的值赋给%d对应的参数也就是下面的argv[1]**
// 用于子进程的 STARTUPINFO 结构
STARTUPINFO si;
ZeroMemory(&si , sizeof(si) ) ;
si.cb = sizeof(si) ; // 必须是本结构的大小
// 返回的用于子进程的进程信息
PROCESS_INFORMATION pi;
// 利用同样的可执行文件和命令行创建进程,并赋于其子进程的性质
BOOL bCreateOK=::CreateProcess(
szFilename, // 产生这个 EXE 的应用程序的名称
szCmdLine, // 告诉其行为像一个子进程的标志
NULL, // 缺省的进程安全性
NULL, // 缺省的线程安全性
FALSE, // 不继承句柄
CREATE_NEW_CONSOLE, // 使用新的控制台
NULL, // 新的环境
NULL, // 当前目录
&si, // 启动信息
&pi) ; // 返回的进程信息
// 对子进程释放引用
if (bCreateOK)
{
CloseHandle(pi.hProcess) ;
CloseHandle(pi.hThread) ;
}
}
int main(int argc, char* argv[] )
{
**//1、在刚开始创建程序时argc=1**
// 确定派生出几个进程,及派生进程在进程列表中的位置
int nClone=0;

// nClone=0;    **//第一次修改将此行的(//)去掉,只剩下(nClone=0;)**

if (argc > 1)**//2、只有满足条件才执行括号内的内容**
{
// 从第二个参数中提取克隆 ID
:: sscanf(argv[1] , "%d" , &nClone) ;**//5、argv[1]从上面获取到增值之后再传递给nClone**
}

// nClone=0;    **//第二次修改将此行的(//)去掉,只剩下(nClone=0;)***

// 显示进程位置
std :: cout << "Process ID:" << :: GetCurrentProcessId()
<< ", Clone ID:" << nClone
<< std :: endl;
// 检查是否有创建子进程的需要
const int c_nCloneMax=5;
if (nClone < c_nCloneMax)
{
// 发送新进程的命令行和克隆号
StartClone(++nClone) ;**//3、创建子进程之后,argc会自增然后大于1**
}
// 等待响应键盘输入结束进程
getchar();
return 0;
}

第一次修改结果如下图:

在这里插入图片描述

第二次修改结果如下图(死循环创建子进程,这时候需要及时强行关闭程序):

在这里插入图片描述

创建子进程流程图

在这里插入图片描述

各位大佬如有更好的建议或者我没有说清楚的地方让各位产生了疑问,各位可以在评论中提出!

猜你喜欢

转载自blog.csdn.net/rothschild666/article/details/95492647