一、实验目的
(1)学会使用 VC 编写基本的 Win32 Consol Application(控制台应用程序)。 (2)通过创建进程、观察正在运行的进程和终止进程的程序设计和调试操作,进一步熟悉操作系统的进程概念,理解 Windows 进程的“一生”。 (3)通过阅读和分析实验程序,学习创建进程、观察进程、终止进程以及父子进程同步的基本程序设计方法。

二、实验内容和步骤
(1)编写基本的 Win32 Consol Application
步骤 1:登录进入 Windows 系统,启动 VC++ 6.0。
步骤 2:在“FILE”菜单中单击“NEW”子菜单,在“projects”选项卡中选择“Win32 Consol Application”,然后在“Project name”处输入工程名,在“Location” 处输入工程目录。创建一个新的控
制台应用程序工程。
步骤 3:在“FILE”菜单中单击“NEW”子菜单,在“Files”选项卡中选择“C++ Source File”, 然后在“File” 处输入 C/C++源程序的文件名。
步骤 4:将清单 1-1 所示的程序清单复制到新创建的 C/C++源程序中。编译成可执行文件。
步骤 5:在“开始”菜单中单击“程序”-“附件”-“命令提示符”命令,进入 Windows“命令提示符”窗口,然后进入工程目录中的 debug 子目录,执行编译好的可执行程序,列出运行结果 (如果运行不成功,则可能的原因是什么?)

答:路径不对或者没有编译文件等。

(2) 创建进程
本实验显示了创建子进程的基本框架。该程序只是再一次地启动自身,显示它的系统进程 ID和它在进程列表中的位置。
步骤 1:创建一个“Win32 Consol Application”工程,然后拷贝清单 1-2 中的程序,编译成可执行文件。
步骤 2:在“命令提示符”窗口运行步骤 1 中生成的可执行文件,列出运行结果。按下 ctrl+alt+del,调用 windows 的任务管理器,记录进程相关的行为属性。
步骤 3:在“命令提示符”窗口加入参数重新运行生成的可执行文件,列出运行结果。按下ctrl+alt+del,调用 windows 的任务管理器,记录进程相关的行为属性。
步骤 4:修改清单 1-2 中的程序,将 nClone 的定义和初始化方法按程序注释中的修改方法进行修改,编译成可执行文件(执行前请先保存已经完成的工作)。再按步骤 2 中的方式运行,看看结果会有什么不一样。列出行结果。从中你可以得出什么结论?说明 nClone 的作用。 变量的定义和初始化方法(位置)对程序的执行结果有影响吗?为什么?

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

(3) 父子进程的简单通信及终止进程
步骤 1:创建一个“Win32 Consol Application”工程,然后拷贝清单 1-3 中的程序,编译成可执行文件。
步骤 2:在 VC 的工具栏单击“Execute Program”(执行程序) 按钮,或者按 Ctrl + F5 键,或者在“命令提示符”窗口运行步骤 1 中生成的可执行文件,列出运行结果。
步骤 3:按源程序中注释中的提示,修改源程序 1-3,编译执行(执行前请先保存已经完成的工作),列出运行结果。在程序中加入跟踪语句,或调试运行程序,同时参考 MSDN 中的帮助文件CreateProcess()的使用方法,理解父子进程如何传递参数。给出程序执行过程的大概描述。
步骤 4:按源程序中注释中的提示,修改源程序 1-3,编译执行,列出运行结果。
步 骤 5 : 参 考 MSDN 中 的 帮 助 文 件 CreateMutex() 、 OpenMutex() 、 ReleaseMutex() 和WaitForSingleObject()的使用方法,理解父子进程如何利用互斥体进行同步的。给出父子进程同步过程的一个大概描述

答:CreateMutex() 创建互斥体hMutexSuicide信号、 OpenMutex()打开互斥体、 ReleaseMutex()释放互斥体、WaitForSingleObject()检测Hhandle信号状态,通过这些只允许有一个状态被创建或者使用也就是信号量唯一,实现进程同步。

三、 程序清单

清单 1-1 一个简单的 Windows 控制台应用程序
// hello 项目
# include <iostream>
void main()
{std::cout << “Hello, Win32 Consol Application” << std :: endl ;
}
清单 1-2 创建子进程
#include <windows.h>
#include <iostream>
#include <stdio.h>
// 创建传递过来的进程的克隆过程并赋于其 ID 值
void StartClone(int nCloneID)
{// 提取用于当前可执行文件的文件名TCHAR szFilename[MAX_PATH] ;GetModuleFileName(NULL, szFilename, MAX_PATH) ;// 格式化用于子进程的命令行并通知其 EXE 文件名和克隆 IDTCHAR szCmdLine[MAX_PATH];
sprintf(szCmdLine,"\"%s\" %d",szFilename,nCloneID);
// 用于子进程的 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[] )
{// 确定派生出几个进程,及派生进程在进程列表中的位置int nClone=0;
//修改语句:int nClone;
//第一次修改:nClone=0;if (argc > 1){// 从第二个参数中提取克隆 ID:: sscanf(argv[1] , "%d" , &nClone) ;}
//第二次修改:nClone=0;
// 显示进程位置std :: cout << "Process ID:" << :: GetCurrentProcessId()<< ", Clone ID:" << nClone<< std :: endl;
// 检查是否有创建子进程的需要const int c_nCloneMax=5;if (nClone < c_nCloneMax){
// 发送新进程的命令行和克隆号StartClone(++nClone) ;}// 等待响应键盘输入结束进程getchar();return 0;
}
清单 1-3 父子进程的简单通信及终止进程的示例程序
// procterm 项目
# include <windows.h>
# include <iostream>
# include <stdio.h>
static LPCTSTR g_szMutexName = "w2kdg.ProcTerm.mutex.Suicide" ;
// 创建当前进程的克隆进程的简单方法
void StartClone()
{// 提取当前可执行文件的文件名TCHAR szFilename[MAX_PATH] ;GetModuleFileName(NULL, szFilename, MAX_PATH) ;// 格式化用于子进程的命令行,字符串“child”将作为形参传递给子进程的 main 函数TCHAR szCmdLine[MAX_PATH] ;
//实验 1-3 步骤 3:将下句中的字符串 child 改为别的字符串,重新编译执行,执行前请先保存已经
完成的工作sprintf(szCmdLine, "\"%s\"child" , szFilename) ;// 子进程的启动信息结构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) ;} }
void Parent()
{// 创建“自杀”互斥程序体HANDLE hMutexSuicide=CreateMutex(NULL, // 缺省的安全性TRUE, // 最初拥有的g_szMutexName) ; // 互斥体名称if (hMutexSuicide != NULL){// 创建子进程std :: cout << "Creating the child process." << std :: endl;StartClone() ;// 指令子进程“杀”掉自身std :: cout << "Telling the child process to quit. "<< std :: endl;
//等待父进程的键盘响应getchar() ;
//释放互斥体的所有权,这个信号会发送给子进程的 WaitForSingleObject 过程
ReleaseMutex(hMutexSuicide) ;// 消除句柄CloseHandle(hMutexSuicide) ;} }
void Child()
{// 打开“自杀”互斥体HANDLE hMutexSuicide = OpenMutex(SYNCHRONIZE, // 打开用于同步FALSE, // 不需要向下传递g_szMutexName) ; // 名称if (hMutexSuicide != NULL){// 报告我们正在等待指令std :: cout <<"Child waiting for suicide instructions. " << std :: endl;//子进程进入阻塞状态,等待父进程通过互斥体发来的信号WaitForSingleObject(hMutexSuicide, INFINITE) ;
//实验 1-3 步骤 4:将上句改为 WaitForSingleObject(hMutexSuicide, 0) ,重新编译执行// 准备好终止,清除句柄std :: cout << "Child quiting." << std :: endl;CloseHandle(hMutexSuicide) ;} }
int main(int argc, char* argv[] )
{// 决定其行为是父进程还是子进程if (argc>1 && :: strcmp(argv[1] , "child" )== 0){Child() ;}else{Parent() ;}
return 0;
}

四、程序流程图
(1)编写基本的Win32 Consol Application

(2)创建进程

(3)父子进程的简单通信及终止进程

五、实验结果与分析
1.编写基本的 Win32 Consol Application:

2.创建进程,实验结果:

将nClone=1修改为1后,运行结果:

结果分析:从main()函数开始,首先判断argc的值(argc初始值默认为1)因为argc不满足大于1,所以不能将argv[1]赋值给nClone;然后nClone < c_nCloneMax ,则调用StartClone (++nClone)函数,创建子进程;创建子进程后,argc的值变为2,然后将自增的nClone赋值argv[1],然后将继续执行main()函数,直到(nClone >c_nCloneMax),跳出,结束创建新进程。

3.父子进程的简单通信及终止进程,实验结果:

修改WaitForSingleObject()后:只允许有一个状态被创建或者使用也就是信号量唯一,实现进程同步。

结果分析:从main()函数开始,首先判断argc的值(argc初始值默认为1),决定进行父进程还是子进程,因为argc不满足大于1,所以调用parent()函数,在执行parent()函数过程中调用StartClone() ;然后通过sprintf(szCmdLine, “”%s"child" , szFilename)将argv[1]赋值child,后面满足条件后调用child()函数;由于设置了互斥信号,则只允许一个进程进行,所以只有当父进程释放互斥信号hMutexSuicide时,子进程检测获得才结束进程。

六、小结与心得体会
通过这个实验加深了我对操作系统的进程概念的了解,理解 Windows 进程的“一生”所有进程都是以调用CreateProcess()API函数开始,以ExitProcess函数结束。学会了创建进程、终止进程以及父子进程同步的基本程序设计方法

操作系统课设——Windows 进程管理相关推荐

  1. 操作系统课设之内存管理

    前言 课程设计开始了,实验很有意思,写博客总结学到的知识 白嫖容易,创作不易,学到东西才是真 本文原创,创作不易,转载请注明!!! 本文链接 个人博客:https://ronglin.fun/arch ...

  2. 操作系统实验:Windows进程管理

    实验项目名称: Windows进程管理 一.实验目的 1.学习windows系统提供的线程创建.线程撤销.线程同步等系统调用: 2.利用C++实现线程创建.线程撤销.线程同步程序: 3.完成思考.设计 ...

  3. 操作系统课设之Windows 进程管理

    前言 课程设计开始了,实验很有意思,写博客总结学到的知识 白嫖容易,创作不易,学到东西才是真 本文原创,创作不易,转载请注明!!! 本文链接 个人博客:https://ronglin.fun/arch ...

  4. 操作系统课设之Linux 进程管理

    前言 课程设计开始了,实验很有意思,写博客总结学到的知识 白嫖容易,创作不易,学到东西才是真 本文原创,创作不易,转载请注明!!! 本文链接 个人博客:https://ronglin.fun/arch ...

  5. 操作系统课设之Windows 的互斥与同步

    前言 课程设计开始了,实验很有意思,写博客总结学到的知识 白嫖容易,创作不易,学到东西才是真 本文原创,创作不易,转载请注明!!! 本文链接 个人博客:https://ronglin.fun/arch ...

  6. 操作系统课设之简单 shell 命令行解释器的设计与实现

    前言 课程设计开始了,实验很有意思,写博客总结学到的知识 白嫖容易,创作不易,学到东西才是真 本文原创,创作不易,转载请注明!!! 本文链接 个人博客:https://ronglin.fun/arch ...

  7. 操作系统课设之基于信号量机制的并发程序设计

    前言 课程设计开始了,实验很有意思,写博客总结学到的知识 白嫖容易,创作不易,学到东西才是真 本文原创,创作不易,转载请注明!!! 本文链接 个人博客:https://ronglin.fun/arch ...

  8. 操作系统课设之虚拟内存页面置换算法的模拟与实现

    前言 课程设计开始了,实验很有意思,写博客总结学到的知识 白嫖容易,创作不易,学到东西才是真 本文原创,创作不易,转载请注明!!! 本文链接 个人博客:https://ronglin.fun/arch ...

  9. 操作系统课设之Linux 进程间通信

    前言 课程设计开始了,实验很有意思,写博客总结学到的知识 白嫖容易,创作不易,学到东西才是真 本文原创,创作不易,转载请注明!!! 本文链接 个人博客:https://ronglin.fun/arch ...

最新文章

  1. oracle 12c java 驱动,oracle12c驱动jar包
  2. Sources for NFC/RFID inspection ( Soft Materials )
  3. Go赋值使用:类型{} 定位使用.
  4. 云计算技术背后的那些天才程序员:KVM之父Avi Kivity
  5. 东京战纪服务器维护中,东京战纪7月21维护公告 当前测试进度介绍
  6. vici 开源asp.net mvc支持asp.net2.0II6.0下部署 实例下载地址
  7. 安卓开发_自定义控件_界面的简单侧滑
  8. 【java学习之路】(java框架)002.Git配置及使用
  9. [转载] python日期时间使用详解和定时器使用讲解
  10. WPF之DatePicker使其只能选择日期,不能输入日期
  11. 大话Neo系列:Merkle Tree
  12. Vmware Workstation虚拟机规划
  13. Ubuntu环境下利用Stress对CPU进行满载及半载压力测试
  14. 非凡的键盘钢琴音源 XLN Audio Addictive Keys Complete 1.1.8 WiN-MAC
  15. gateway笔记TODO
  16. 策略模式--strategy
  17. Python3 编程第一弹 斐波纳契数列
  18. Java入门和第一个项目
  19. 【云扩RPA】Table
  20. 思科ASA防火墙:内网telnet远程控制防火墙 外网ssh远程控制防火墙

热门文章

  1. 【性能测试】记一次性能测试
  2. 关于门控时钟的毛刺解决
  3. G6-Editor 编辑器入门使用教程
  4. java holder详解_connection holder is null 异常详解
  5. Linux CRDA(Central Regulatory Domain Agent)简介
  6. 生信分析学习笔记:(2)GO KEGG分析
  7. 版本控制管理工具Git/SVN
  8. 【HDFS】HDFS文件块大小(重点)
  9. Taven教授:解决失眠的好办法
  10. 并发编程-基础篇五-ThreadLocal