欢迎来到三一办公! | 帮助中心 三一办公31ppt.com(应用文档模板下载平台)
三一办公
全部分类
  • 办公文档>
  • PPT模板>
  • 建筑/施工/环境>
  • 毕业设计>
  • 工程图纸>
  • 教育教学>
  • 素材源码>
  • 生活休闲>
  • 临时分类>
  • ImageVerifierCode 换一换
    首页 三一办公 > 资源分类 > PPT文档下载  

    编程中的进程管理.ppt

    • 资源ID:6001989       资源大小:490.54KB        全文页数:67页
    • 资源格式: PPT        下载积分:10金币
    快捷下载 游客一键下载
    会员登录下载
    三方登录下载: 微信开放平台登录 QQ登录  
    下载资源需要10金币
    邮箱/手机:
    温馨提示:
    用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)
    支付方式: 支付宝    微信支付   
    验证码:   换一换

    加入VIP免费专享
     
    账号:
    密码:
    验证码:   换一换
      忘记密码?
        
    友情提示
    2、PDF文件下载后,可能会被浏览器默认打开,此种情况可以点击浏览器菜单,保存网页到桌面,就可以正常下载了。
    3、本站不支持迅雷下载,请使用电脑自带的IE浏览器,或者360浏览器、谷歌浏览器下载即可。
    4、本站资源下载后的文档和图纸-无水印,预览文档经过压缩,下载后原文更清晰。
    5、试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。

    编程中的进程管理.ppt

    ,Windows系统编程实用教程,授课教师:职务:,第7章 进程编程,课程描述大多数应用程序都以进程的形式运行,有时还需要在应用程序里运行或结束其他进程。本章将介绍Windows进程编程的方法。,本章知识点,7.1 进程编程基础7.2 基本进程编程7.3 进程间通信,7.1 进程编程基础,7.1.1 什么是进程7.1.2 进程的状态,7.1.1 什么是进程,进程是正在运行的程序的实例。每个运行的Visual C+项目都对应一个进程,每个进程至少包含一个线程,它从main()函数开始执行,直到执行return语句返回,主线程结束,该进程也被从内存中卸载。进程由如下几个部分组成。与程序相关联的可执行代码的映像;内存空间(通常是虚拟内存中的一些区域),其中保存可执行代码、进程的特定数据、用于记录活动例程和其他事件的调用栈、用于保存实时产生的中间计算结果的堆(heap)。分配给进程的资源的操作系统描述符(比如文件句柄)以及其他数据资源。安全属性,比如进程的所有者和权限。处理器的状态,比如寄存器的内容、物理内存地址等。,7.1.2 进程的状态,7.2 基本进程编程,7.2.1 创建进程7.2.2 枚举系统进程7.2.3 终止进程,7.2.1 创建进程,在应用程序中可以调用CreateProcess()函数创建一个新进程、运行其他程序,函数原型如下:BOOL WINAPI CreateProcess(_in LPCTSTR lpApplicationName,_in_out LPTSTR lpCommandLine,_in LPSECURITY_ATTRIBUTES lpProcessAttributes,_in LPSECURITY_ATTRIBUTES lpThreadAttributes,_in BOOL bInheritHandles,_in DWORD dwCreationFlags,_in LPVOID lpEnvironment,_in LPCTSTR lpCurrentDirectory,_in LPSTARTUPINFO lpStartupInfo,_out LPPROCESS_INFORMATION lpProcessInformation);,参数说明,lpApplicationName,要执行的应用程序名,可以包括结对路径和文件名,通常可以为NULL。lpCommandLine,要执行的命令行。lpProcessAttributes,新进程的安全描述符。lpThreadAttributes,指定主线程的安全描述符。如果为NULL,则使用默认的安全描述符。bInheritHandles,指示新进程是否从调用进程处继承句柄。dwCreationFlags,指定附加的、用来控制优先类和进程创建的标志。lpEnvironment,指向新进程的环境块。如果为NULL,则使用调用CreateProcess()函数的进程的环境。,【例7.1】,调用CreateProcess()函数运行Windows计算器程序,并显示新进程的ID号,及其主线程的Id号,代码如下:#include stdafx.h#include int _tmain(int argc,_TCHAR*argv)char szCommandLine=calc.exe;STARTUPINFO si=sizeof(si);PROCESS_INFORMATION pi;si.dwFlags=STARTF_USESHOWWINDOW;/指定wShowWindow成员有效si.wShowWindow=TRUE;/显示新建进程的主窗口,接上,BOOL bRet=CreateProcess(NULL,/不在此指定可执行文件的文件名szCommandLine,/命令行参数NULL,/默认进程安全性NULL,/默认进程安全性FALSE,/指定当前进程内句柄不可以被子进程继承CREATE_NEW_CONSOLE,/为新进程创建一个新的控制台窗口NULL,/使用本进程的环境变量NULL,/使用本进程的驱动器和目录,【例7.1】的运行结果,ShellExecute()函数,HINSTANCEShellExecute(HWNDhwnd,/指定显示用户界面和错误信息的窗口句柄LPCTSTRlpOperation,/对指定文件要执行的操作LPCTSTRlpFile,/要执行操作的文件或对象LPCTSTRlpParameters,/指定传送给应用程序的参数LPCTSTRlpDirectory,/指定执行操作的工作目录INTnShowCmd/指定应用程序如何显示。SW_HIDE表示隐藏窗口,SW_MAXIMIZE表示最大化窗口,SW_MINIMIZE表示最小化窗口,SW_SHOW表示在当前位置上以当前大小显示窗口,等等);,pOperation参数的取值,【例7.2】,【例7.2】调用ShellExecute()函数访问google网站,代码如下:#include stdafx.h#include windows.h”int _tmain(int argc,_TCHAR*argv)ShellExecute(NULL,open,http:/,SW_SHOW);return 0;,7.2.2 枚举系统进程,1使用EnumProcesses()函数2使用进程快照,1使用EnumProcesses()函数,BOOL WINAPI EnumProcesses(_out DWORD*pProcessIds,/用于接收进程标示符列表的数组 _in DWORD cb,/数组pProcessIds的大小,单位是字节 _out DWORD*pBytesReturned/数组pProcessIds中返回数据的大小,单位是字节);如果函数执行成功,则返回一个非0值;否则返回0。,【例7.3】,调用EnumProcess()函数枚举当前Windows运行进程的标示符(PID),代码如下:#include stdafx.h#include#include#pragma comment(lib,Psapi.lib)int _tmain(int argc,_TCHAR*argv)/用于接收返回的进程ID信息的数组 DWORD dwProcs1024*2;DWORD dwNeeded;/返回进程数组的大小/枚举所有进程ID。,接上,if(!EnumProcesses(dwProcs,sizeof(dwProcs),【例7.3】的运行结果,2使用进程快照,HANDLE WINAPI CreateToolhelp32Snapshot(DWORD dwFlags,/指定快照中包含的对象 DWORD th32ProcessID/指定获取进程快照的PID。如果为0,则获取当前系统进程列表);如果函数执行成功,则返回进程快照的句柄;否则返回INVALID_HANDLE_VALUE。,Process32First()函数,调用Process32First()函数可以从进程快照中获取第1个进程的信息,函数原型如下:BOOL WINAPI Process32First(HANDLE hSnapshot,/之前调用createtoolhelp32napshot()函数得到的进程快照句柄 LPPROCESSENTRY32 lppe/包含进程信息的结构体);,结构体LPPROCESSENTRY32,LANA_ENUM结构体中包含当前逻辑网络适配器的数量。当一个物理网络适配器绑定到一个网络协议时,就对应一个逻辑网络适配器。执行NCB命令NCBENUM可以向LANA_ENUM结构体中填充逻辑网络适配器的个数和逻辑网络适配器编号,此时NCB结构体中的ncb_buffer成员变量指向LANA_ENUM结构体。LANA_ENUM结构体的定义代码如下:typedef struct _LANA_ENUM UCHAR length;UCHAR lanaMAX_LANA;LANA_ENUM,*PLANA_ENUM;参数说明如下:length,系统中包含的逻辑网络适配器数量。lanaMAX_LANA,系统中包含的逻辑网络适配器编号数组。,Process32Next()函数,调用Process32Next()函数可以从进程快照中获取下一个进程的信息,函数原型如下:BOOL WINAPI Process32Next(HANDLE hSnapshot,、/之前调用createtoolhelp32napshot()函数得到的进程快照句柄 LPPROCESSENTRY32 lppe/包含进程信息的结构体);如果函数执行成功,则返回TRUE;否则返回FALSE。,【例7.4】,利用进程快照枚举当前Windows运行进程的信息,代码如下:#include stdafx.h#include windows.h#include tlhelp32.hint _tmain(int argc,_TCHAR*argv)PROCESSENTRY32 pe;/设置结构体pe的大小pe.dwSize=sizeof(pe);/获取系统内进程的快照HANDLE hProcessSnap=:CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);if(hProcessSnap=INVALID_HANDLE_VALUE)printf(CreateToolhelp32Snapshot error.n);return-1;,接上,/遍历进程快照,显示每个进程的信息BOOL bMore=:Process32First(hProcessSnap,4ASTAT结构体,ASTAT结构体用于描述网络适配器的状态和名字信息,定义代码如下:typedef struct ADAPTER_STATUS adapt;NAME_BUFFER NameBuff30;ASTAT;参数adapt表示网络适配器的状态信息,参数NameBuff表示网络适配器中保存的本地网络名字信息。,【例7.4】的运行结果,7.2.3 终止进程,进程从主函数的第一行代码开始执行,直到主函数结束时终止;也可以强制结束一个进程。当进程被终止时,系统会进行下面的操作:进程中的所有线程都被标记为“终止”状态;分配给进程的所有资源都会被释放掉;所有与该进程相关的内核对象都会被关闭;从内存中移除该进程的代码;系统设置进程的退出代码;将该进程对象设置为“受信”(Sigaled)状态。,GetExitCodeProcess()函数,调用GetExitCodeProcess()函数可以获取进程的终止状态,函数原型如下:BOOL WINAPI GetExitCodeProcess(_inHANDLE hProcess,/进程句柄 _outLPDWORD lpExitCode/用于接收进程的终止状态);如果函数执行成功,则返回TRUE;否则返回FALSE。当进程在运行中时,其终止状态为STILL_ACTIVE。当进程被终止时,其终止状态变成退出代码。,ExitProcess()函数,在进程中调用ExitProcess()函数终止其自身中所有的线程,函数原型如下:VOID WINAPI ExitProcess(_inUINT uExitCode/退出代码);,TerminateProcess()函数,调用TerminateProcess()函数可以终止指定的进程,函数原型如下:BOOL WINAPI TerminateProcess(_inHANDLE hProcess,/要终止的进程句柄 _inUINT uExitCode/退出代码);,7.3 进程间通信,7.3.1 通过自定义消息进行通信7.3.2 通过管道进行通信7.3.3 使用互斥体7.3.4 通过共享内存进行通信,7.3.1 通过自定义消息进行通信,1定义自定义消息的代码2发送消息3消息处理函数,1定义自定义消息的代码,为了唯一标识自定义消息,需要为其定义一个消息代码。自定义的消息代码都比WM_USER要大,因为0 WM_USER-1是保留给系统消息使用。可以使用下面的代码定义一个自定义消息WM_MY_MESSAGE:#define WM_MY_MESSAGE(WM_USER+100),2发送消息,调用PostMessage()函数将消息放置到与创建指定窗口的进程相关联的消息队列中,函数不需要等待接收方接受和处理消息就直接返回。函数原型如下:BOOL PostMessage(HWND hWnd,/接收消息的窗口句柄,使用HWND_BROADCAST表示所有顶层窗口 UINT Msg,/发送消息的代码 WPARAM wParam,/指定消息的附加信息 LPARAM lParam/指定消息的附加信息);,FindWindow()函数,HWND FindWindow(LPCTSTR lpClassName,/窗口类名,通常为NULL LPCTSTR lpWindowName/要查找窗口的标题);,3消息处理函数,在接收端需要设计一个消息处理函数,它的格式如下:LRESULTOnMyMsg(WPARAM wParam,LPARAM lParam)/处理代码return 0;参数wParam和lParam用于接收PostMessage()函数发送消息时指定的参数。,将消息与其处理函数映射起来,定义消息处理函数后还要将消息与其处理函数映射起来。在每个MFC对话框对应的.cpp文件中,都在BEGIN_MESSAGE_MAP宏和END_MESSAGE_MAP()宏之间定义消息与其处理函数映射的,例如:BEGIN_MESSAGE_MAP(CReceiverDlg,CDialog)ON_WM_SYSCOMMAND()ON_WM_PAINT()ON_WM_QUERYDRAGICON()/AFX_MSG_MAPEND_MESSAGE_MAP(),BEGIN_MESSAGE_MAP宏,BEGIN_MESSAGE_MAP宏用于标识消息映射的开始,其原型如下:BEGIN_MESSAGE_MAP(theClass,baseClass)参数theClass指定消息映射所属的类,通常是窗口类;参数baseClass指定参数theClass的基类。在BEGIN_MESSAGE_MAP宏和END_MESSAGE_MAP()宏之间添加一条ON_MESSAGE宏用于定义自定义消息及其处理函数的映射。ON_MESSAGE宏的原型如下:ON_MESSAGE(message,memberFxn)参数message用于指定自定义消息的代码,参数memberFxn指定消息处理函数。,【例7.5】,设计一个利用自定义消息实现进程间通信的例子。1设计发送端项目2设计接收端项目,1设计发送端项目,创建一个基于对话框的MFC应用程序Sender,定义自定义消息WM_MY_MESSAGE,代码如下:#define WM_MY_MESSAGE(WM_USER+999),单击“发送消息”按钮的代码,void CSenderDlg:OnBnClickedButtonSendmsg()HWND hWnd=:FindWindow(NULL,Receiver);:PostMessage(hWnd,WM_MY_MESSAGE,(WPARAM)999,NULL);,2设计接收端项目,创建一个基于对话框的MFC应用程序Receiver,定义自定义消息WM_MY_MESSAGE,代码如下:#define WM_MY_MESSAGE(WM_USER+999)编写消息处理函数OnMyMsg(),代码如下:LRESULT CReceiverDlg:OnMyMsg(WPARAM wParam,LPARAM lParam)char msg100;sprintf(msg,%d,(int)wParam);MessageBox(msg,收到消息);return 0;,添加自定义消息及其处理函数的映射,BEGIN_MESSAGE_MAP(CReceiverDlg,CDialog)ON_MESSAGE(WM_MY_MESSAGE,OnMyMsg)/映射消息和处理函数/AFX_MSG_MAPEND_MESSAGE_MAP(),7.3.2 通过管道进行通信,管道(Pipe)是由标准输入输出流构成的进程链。一个进程的输出直接作为下一个进程的输入。每个连接都是一个匿名管道。管道包含一个写句柄和一个读句柄。一个进程使用写句柄向管道里写入数据,另一个进程使用读句柄从管道中读取数据。调用CreatePipe()函数可以创建管道,函数原型如下:BOOL WINAPI CreatePipe(_out PHANDLE hReadPipe,/管道的读句柄 _out PHANDLE hWritePipe,_in LPSECURITY_ATTRIBUTES lpPipeAttributes,_in DWORD nSize);,【例7.6】,设计一个利用管道实现进程间通信的例子。主进程Server的代码如下:#include stdafx.h#include int _tmain(int argc,_TCHAR*argv)HANDLE hRead;/管道读句柄HANDLE hWrite;/管道写句柄SECURITY_ATTRIBUTES sa;/设置管道属性sa.nLength=sizeof(SECURITY_ATTRIBUTES);sa.lpSecurityDescriptor=NULL;sa.bInheritHandle=TRUE;/指定管道句柄可以被子进程继承BOOL bRet=CreatePipe(,接上,/得到本进程的当前标准输出,以备将来恢复HANDLE hTemp=GetStdHandle(STD_OUTPUT_HANDLE);/设置标准输出到匿名管道SetStdHandle(STD_OUTPUT_HANDLE,hWrite);STARTUPINFO si;GetStartupInfo(,接上,/读管道直至管道关闭char ReadBuf100;DWORD ReadNum;/循环从管道中读取数据while(ReadFile(hRead,ReadBuf,100,子进程Client的代码,#include stdafx.h#include#include using namespace std;int _tmain(int argc,_TCHAR*argv)for(int i=0;i 10;i+)/发送一些数据到标准输出和标准错误printf(i=%d;,i);/打印提示cout 标准输出:i endl;/打印到标准输出cerr 标准错误:i endl;/打印到标准错误return 0;,【例7.6】的运行结果,7.3.3 使用互斥体,HANDLE WINAPI CreateMutex(_in LPSECURITY_ATTRIBUTES lpMutexAttributes,/互斥体对象的安全属性,如果为NULLZ,则互斥体对象不能被子进程继承 _in BOOL bInitialOwner,/初始化互斥对象的所有者 _in LPCTSTR lpName/指定互斥对象的名字);如果在不同进程间使用互斥体,则该互斥体对象是全局的。全局互斥体对象的名字必须以“Global”为前缀,而本地互斥体对象的名字则以“Local”为前缀。,【例7.7】,设计一个利用互斥体防止运行一个应用程序的多个实例的例子Mutex,代码如下:int _tmain(int argc,_TCHAR*argv)CreateMutex(NULL,TRUE,GlobalMyMutex001);if(GetLastError()=ERROR_ALREADY_EXISTS)printf(应用程序已经运行!n);exit(0);printf(已进入应用程序.n);system(pause);return 0;,第1次运行Mutex.exe的结果,7.3.4 通过共享内存进行通信,每个Windows进程都有其私有的内存空间。任何进程都不能修改其他进程的内存空间,包括变量和对象等。但是多个进程间可以通过一块共享内存进行通信。共享内存是允许多个进程同时访问的内存,不同的进程可以通过共享内存进行通讯,也可以避免在不同的程序中保存多余的数据备份。通常可以使用内存映射文件实现共享内存,用内存映射文件是由一个文件到一块内存的映射。内存映射文件与虚拟内存有些类似,通过内存映射文件可以保留一个地址空间的内存区域,同时将物理存储器提交给此区域,内存文件映射的物理存储器来自一个已经存在于磁盘上的文件,而且在对该文件进行操作之前必须首先对文件进行映射。使用内存映射文件处理存储于磁盘上的文件时,将不必再对文件执行过多的I/O操作,因此,内存映射文件在处理大数据量的文件时能起到相当重要的作用。,CreateFileMapping()函数,HANDLE CreateFileMapping(HANDLE hFile,LPSECURITY_ATTRIBUTES lpFileMappingAttributes,DWORD flProtect,DWORD dwMaximumSizeHigh,DWORD dwMaximumSizeLow,LPCTSTR lpName);,参数说明,hFile:创建映射对象的文件句柄,如果使用INVALID_HANDLE_VALUE,则在物理内存中创建映射对象。lpFileMappingAttributes:被忽略,必须为NULL。flProtect,文件视图的保护方式。dwMaximumSizeHigh,指定文件映射对象最大大小的高32位。dwMaximumSizeLow,指定文件映射对象最大大小的低32位。lpName,映射对象的名字,如果是全局映射对象,则名字可以以“Global”前缀开始。,MapViewOfFile()函数,调用MapViewOfFile()函数可以将指定的文件视图映射到调用进程的地址空间,函数原型如下:LPVOID MapViewOfFile(HANDLE hFileMappingObject,/文件映射对象的句柄,通常由CreateFileMapping()函数返回 DWORD dwDesiredAccess,/对文件视图的访问类型 DWORD dwFileOffsetHigh,/指定开始映射的文件偏移量的高32位 DWORD dwFileOffsetLow,/指定开始映射的文件偏移量的低32位 DWORD dwNumberOfBytesToMap/指定文件映射的字节数。如果为0,则映射整个文件。);,OpenFileMapping()函数,HANDLE WINAPI OpenFileMapping(_in DWORD dwDesiredAccess,/访问权限 _in BOOL bInheritHandle,/指定子进程是否可以继承句柄 _in LPCTSTR lpName/指定要打开指定的文件映射对象的名字);如果函数执行成功,则返回打开指定的文件映射对象句柄;否则返回NULL。可以调用GetLastError()函数获取错误代码。,UnmapViewOfFile()函数,调用UnmapViewOfFile()函数可以从调用进程的地址空间中解除文件视图的映射。函数原型如下:BOOL UnmapViewOfFile(LPCVOID lpBaseAddress/要解除的文件视图映射的基地址);,【例7.8】,计一个创建文件映射对象,并向映射视图中写入数据的例子Process1,代码如下:#include stdafx.h#include#include#include#define BUF_SIZE 256/共享内存的大小TCHAR szName=TEXT(GlobalMyFileMappingObject);/文件映射对象的名字TCHAR szMsg=TEXT(Message from process1);/向共享内存中写入的数据int _tmain(int argc,_TCHAR*argv)HANDLE hMapFile;LPCTSTR pBuf;,接上,/创建文件映射对象 hMapFile=CreateFileMapping(INVALID_HANDLE_VALUE,/使用页文件 NULL,PAGE_READWRITE,/可读写 0,BUF_SIZE,/文件映射对象的大小 szName);/文件映射对象的名字 if(hMapFile=NULL)printf(Could not create file mapping object(%d).n,GetLastError();return 1;,接上,/将指定的文件视图映射到调用进程的地址空间,得到的pBuf地址就是共享内存的开始地址,共享内存的大小为BUF_SIZE pBuf=(LPTSTR)MapViewOfFile(hMapFile,/映射对象的句柄 FILE_MAP_ALL_ACCESS,/可读写 0,0,BUF_SIZE);if(pBuf=NULL)printf(Could not map view of file(%d).n,GetLastError();return 2;/向共享内存中写入数据 CopyMemory(PVOID)pBuf,szMsg,strlen(szMsg);system(pause);/等待其他进程从共享内存中读取数据/从调用进程的地址空间中解除文件视图的映射 UnmapViewOfFile(pBuf);/关闭映射对象的句柄 CloseHandle(hMapFile);return 0;,设计一个从Process1创建的映射视图中读取数据的例子Process2,#include stdafx.h#include#include#include#define BUF_SIZE 256/共享内存的大小TCHAR szName=TEXT(GlobalMyFileMappingObject);/文件映射对象的名字int _tmain(int argc,_TCHAR*argv)HANDLE hMapFile;LPCTSTR pBuf;/打开例.8中创建的文件映射对象 hMapFile=OpenFileMapping(FILE_MAP_ALL_ACCESS,/可读写 FALSE,/指定子进程不继承句柄 szName);/指定要打开指定的文件映射对象的名字,接上,if(hMapFile=NULL)printf(Could not open file mapping object(%d).n,GetLastError();system(pause);return 1;/将指定的文件视图映射到调用进程的地址空间,得到的pBuf地址就是共享内存的开始地址,共享内存的大小为BUF_SIZE pBuf=(LPTSTR)MapViewOfFile(hMapFile,/映射对象的句柄 FILE_MAP_ALL_ACCESS,/可读写 0,0,BUF_SIZE);,接上,if(pBuf=NULL)printf(Could not map view of file(%d).n,GetLastError();system(pause);return 2;/打印共享内存中的数据 printf(Read from Map file:%snn,pBuf);/从调用进程的地址空间中解除文件视图的映射 UnmapViewOfFile(pBuf);/关闭映射对象的句柄 CloseHandle(hMapFile);system(pause);return 0;,Process2的运行结果,

    注意事项

    本文(编程中的进程管理.ppt)为本站会员(sccc)主动上传,三一办公仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知三一办公(点击联系客服),我们立即给予删除!

    温馨提示:如果因为网速或其他原因下载失败请重新下载,重复下载不扣分。




    备案号:宁ICP备20000045号-2

    经营许可证:宁B2-20210002

    宁公网安备 64010402000987号

    三一办公
    收起
    展开