admin 管理员组

文章数量: 887021


2023年12月19日发(作者:phpsocket非阻塞)

实验4 进程控制

1、实验目的

(1) 通过对WindowsXP进行编程,来熟悉和了解系统。

(2) 通过分析程序,来了解进程的创建、终止。

2、实验工具

(1) 一台WindowsXP操作系统的计算机。

(2) 计算机装有Microsoft Visual Studio C++6.0专业版或企业版。

3、预备知识

(3)

·CreateProcess()调用:创建一个进程。

(4) ·ExitProcess()调用:终止一个进程。

4、实验编程

(1)编程一 利用CreateProcess()函数创建一个子进程并且装入画图程序()。阅读该程序,完成实验任务。源程序如下:

# include < stdio.h >

# include < windows.h >

int main(VOID)

﹛ STARTUPINFO si;

PROCESS INFORMATION pi;

ZeroMemory(&si,sizeof(si));

=sizeof(si);

ZeroMemory(&pi,sizeof(pi));

if(!CreateProcess(NULL,

“c: WINDOWSsystem32 ”,

NULL,

NULL,

FALSE,

0,

NULL,

NULL,

&si,&pi))

﹛fprintf(stderr,”Creat Process Failed”);

return — 1;

WaitForSingleObject(ss,INFINITE);

Printf(“child Complete”);

CloseHandle(ss);

CloseHandle(pi hThread);

在“命令提示符”窗口运行CL命令产生可执行程序:

C: >CL

实验任务:写出程序的运行结果。

4.正在运行的进程

(2)、编程二 下面给出了一个使用进程和操作系统版本信息应用程序(文件名为)。它利用进程信息查询的API函数GetProcessVersion()与GetVersionEx()的共同作用。确定运行进程的操作系统版本号。阅读该程序并完成实验任务。

#include

#include

//利用进程和操作系统的版本信息的简单示例

Void main()

//提取这个进程的ID号

DWORD dwIdThis=::GetCurrentProcessId();

//获得这一进程和报告所需的版本,也可以发送0以便指明这一进程

DWORD dwVerReq=::GetProcessVersion(dwIdThis);

WORD wMajorReq=::(WORD)dwVerReq>16);

WORD wMinorReq=::(WORD)dwVerReq & oxffff);

std::cout< <”Process ID:”<

< <”,requires OS:”<

//设置版本信息的数据结构,以便保存操作系统的版本信息

OSVERSIONINFOEX osvix;

::ZeroMemory(&osvix,sizeof(osvix));

rsionInfoSize=sizeof(osvix);

//提取版本信息和报告

::GetVersionEx(reinterpret cast(&osvix));

Std::cout< <”Running on OS:”<

<

//如果是NTS(Windows2000)系统,则提高其优先权

If(formld==VER PLATFORM WIN32 NT& &

rVersion>=5

//改变优先级

::SerPriorityClass(

::GetCurrentProcess() //利用这一进程

HIGH PRIORITY CLASS); //改变为high

//报告给用户

Std::cout< <”Task Manager should now now indicate this”

“process is high priority.”<

实验参考:①在Visual C++窗口的工具栏中单击“打开”按钮,在“打开“对话框中找到并打开源程序。

②单击Build菜单中的Compile 命令,再单击“是”按钮确认。系统对源程序进行编译。

③编译完成后,单击Build菜单中的Build 命令,建立可执行文件。

④在工具栏单击Execute Program(执行程序)按钮,执行程序。

实验任务:写出程序运行后的以下几项结果。

当前PID信息 。

当前操作系统版本 。

系统提示信息 。

5、终止进程

(3)编程三 下面给出了一个终止进程的应用程序(文件名为),它先创建一个子进程,然后命令它发出“自杀弹”互斥体去终止自身的运行。阅读该程序并完成实验任务。

#include

#include

#include

satic LPCTSTR g szMutexName=”e”;

//创建当前进程的克隆进程的简单方法

Void StartClone()

//提取当前可执行文件的文件名

TCHAR szFilename﹝MAX PATH﹞

::GetModuleFileName(NULL,szFilename,MAX PATH);

//格式化用于子进程的命令行,指明它是一个EXE文件和子进程

TCHAR szCmdLine﹝MAX PATH﹞;

::sprintf(szCmdLine,””%s”child”,szFilename);

//子进程的启动信息结构

STARTUPINFO si;

::ZeroMemory(reinterpret cast(&si),sizeof(si));

=sizeof(si); //应当是此结构的大小

//返回的用于子进程的进程信息

PROCESS INFORMATION pi;

//用同样的可执行文件名和命令行创建进程,并指明它是一个子进程

BOOL bCreateOK=::CreateProcess(

SzFilename, //产生的应用程序名称(本EXE文件)

SzCmdLine, //告诉人们这是一个子进程的标志

NULL, //用于进程的默认的安全性

NULL, //用于线程的默认安全性

FALSE, //不继承句柄

CREATE NEW CONSOLE, //创建新窗口,使输出更直观

NULL, //新环境

NULL, //当前目录

&si, //启动信息结构

&pi); //返回的进程的信息

//释放指向子进程的引用

if(bCreateOK)

::CloseHandle(ss);

::CloseHandle(d);

Void Parent()

//创建“自杀”互斥程序体

HANDLE hMutexSuicide=::CreatgeMutex(

NULL, //默认的安全性

TRUE, //最初拥有的

g szMutexName); //为其命名

if(hMutexSuicide !=NULL)

//创建子进程

std::cout< <”Creating the child process.”<

::StartClone();

//暂停

::sleep(5000);

//指令子进程“杀”掉自身

std::cout< <”Telling the child process to quit.”<

::ReleaseMutex(hMutexSuicide);

//消除句柄

::CloseHandle(hMutexSuicide);

Void Child()

//打开“自杀”互斥体

HANDLE hMutexSuicide=::OpenMutex(

SYNCHRONIZE, //打开用于同步

FALSE, //不需要向下传递

g szMutexName); //名称

if ( hMutexSuicide !=NULL)

//报告正在等待指令

Std::cout< <”Child waiting for suicide instructions.”<

::WaitForSingleObject(hMutexSuicide,INFINITE);

//报告准备好终止,消除句柄

Std:cout< <”Child quiting.”<

::CloseHandle(hMutexSuicide); ::sleep(1000);

int main(int arqc,char * argv﹝﹞)

//决定其行为是父进程还是子进程

if(argc>1 & & ::strcmp(argv﹝1﹞,”child”)==0)

Child();

else

Parent();

Return 0;

分析:程序说明了一个进程从“生”到“死”的整个一生,第一次执行时,它创建一个子进程,其行为如同“父亲”。在创建子进程之前,先创建一个互斥的内核对象,

其行为对于子进程来说,如同一个“自杀弹”。当创建子进程时,就打开了互斥体并在其他线程中进行别的处理工作,同时等待着父进程使用ReleaseMutex()API发出“死亡”信号。然后用Sleep()API调用来模拟父进程处理其他工作,等完成时,指令子进程终止。

当调用ExitProcess()时要小心,进程中的所有线程都被立刻通知停止。在设计应用程序时,必须让主线程在正常的C++运由期关闭(这是由编译器提供默认行为)之后来调用这一函数。当它转向受信状态时,通常可创建一个每个活动线程都可等待和停止的终止事件。

在正常的终止操作中,进程的每个工作线程都要终止,由主线程序员调用ExitProcess()。接着,管理层对进程增加的所有对象释放引用,并将用GetExitChodeProcess()建立的退出代码从STILL ACTIVE改变为ExitProcess()调用中返回的值。最后,主线程对象也如同进程对象一样转变为受信状态。

等到所有打开的句柄都关闭之后,管理层的对象管理器才销毁进程对象本身。还没有一种函数可取得终止后的进程对象为其参数,从而使具其“复活”。当进程对象引用一个终止了的对象时,有好几个API函数仍然是有用的。进程可使用退出代码将终止方式通知给调用GetExitCodeProcess ()的其他进程。同时,GetProcessTimes()API函数可向主调者显示

进程的终止时间。

实验参考:①在Visual C++窗口的工具栏中单击“打开”按钮,在“打开”对话框中找到并打开命令源程序。

②单击Build菜单中的Compile 命令,再单击“是”按钮确认。系统对源程序进行编译。

③编译完成后,单击Build菜单中的命令,建立可执行文件。

实验任务:写出程序的运行结果。


本文标签: 进程 终止 程序 创建