编程中的进程管理

上传人:博****1 文档编号:584207219 上传时间:2024-08-30 格式:PPT 页数:67 大小:490.52KB
返回 下载 相关 举报
编程中的进程管理_第1页
第1页 / 共67页
编程中的进程管理_第2页
第2页 / 共67页
编程中的进程管理_第3页
第3页 / 共67页
编程中的进程管理_第4页
第4页 / 共67页
编程中的进程管理_第5页
第5页 / 共67页
点击查看更多>>
资源描述

《编程中的进程管理》由会员分享,可在线阅读,更多相关《编程中的进程管理(67页珍藏版)》请在金锄头文库上搜索。

1、For:分类信息From:新闻WindowsWindows系统编程实用教程系统编程实用教程系统编程实用教程系统编程实用教程授课教师:授课教师:职务:职务:For:分类信息From:新闻第第7章章进程编程进程编程课程描述课程描述课程描述课程描述大多数应用程序都以进程大多数应用程序都以进程大多数应用程序都以进程大多数应用程序都以进程的形式运行,有时还需要的形式运行,有时还需要的形式运行,有时还需要的形式运行,有时还需要在应用程序里运行或结束在应用程序里运行或结束在应用程序里运行或结束在应用程序里运行或结束其他进程。本章将介绍其他进程。本章将介绍其他进程。本章将介绍其他进程。本章将介绍Windows

2、WindowsWindowsWindows进程编程的方法。进程编程的方法。进程编程的方法。进程编程的方法。For:分类信息From:新闻本章知识点本章知识点7.1 7.1 进程编程基础进程编程基础7.2 7.2 基本进程编程基本进程编程7.3 7.3 进程间通信进程间通信For:分类信息From:新闻7.1进程编程基础进程编程基础7.1.1 7.1.1 什么是什么是进程进程7.1.2 7.1.2 进程的状态进程的状态For:分类信息From:新闻7.1.1什么是什么是进程进程进程是正在运行的程序的实例。每个运行的进程是正在运行的程序的实例。每个运行的VisualC+项目都对应一项目都对应一个进

3、程,每个进程至少包含一个线程,它从个进程,每个进程至少包含一个线程,它从main()函数开始执函数开始执行,直到执行行,直到执行return语句返回,主线程结束,该进程也被从内语句返回,主线程结束,该进程也被从内存中卸载。存中卸载。进程由如下几个部分组成。进程由如下几个部分组成。p与程序相关联的可执行代码的映像;与程序相关联的可执行代码的映像;p内存空间(通常是虚拟内存中的一些区域),其中保存内存空间(通常是虚拟内存中的一些区域),其中保存可执行代码、进程的特定数据、用于记录活动例程和其他可执行代码、进程的特定数据、用于记录活动例程和其他事件的调用栈、用于保存实时产生的中间计算结果的堆事件的调

4、用栈、用于保存实时产生的中间计算结果的堆(heap)。)。p分配给进程的资源的操作系统描述符(比如文件句柄)分配给进程的资源的操作系统描述符(比如文件句柄)以及其他数据资源。以及其他数据资源。p安全属性,比如进程的所有者和权限。安全属性,比如进程的所有者和权限。p处理器的状态,比如寄存器的内容、物理内存地址等。处理器的状态,比如寄存器的内容、物理内存地址等。For:分类信息From:新闻7.1.2进程的状态进程的状态 For:分类信息From:新闻7.2基本进程编程基本进程编程7.2.1 7.2.1 创建进程创建进程7.2.2 7.2.2 枚举系统进程枚举系统进程7.2.3 7.2.3 终止终

5、止进程进程For:分类信息From:新闻7.2.1创建进程创建进程p在应用程序中可以调用在应用程序中可以调用CreateProcess()CreateProcess()函数创建一个新进程、运行函数创建一个新进程、运行其他程序,函数原型如下:其他程序,函数原型如下:BOOL WINAPI CreateProcess(BOOL WINAPI CreateProcess( _in LPCTSTR _in LPCTSTR lpApplicationNamelpApplicationName, , _in_out LPTSTR _in_out LPTSTR lpCommandLinelpCommandL

6、ine, , _in LPSECURITY_ATTRIBUTES _in LPSECURITY_ATTRIBUTES lpProcessAttributeslpProcessAttributes, , _in LPSECURITY_ATTRIBUTES _in LPSECURITY_ATTRIBUTES lpThreadAttributeslpThreadAttributes, , _in BOOL _in BOOL bInheritHandlesbInheritHandles, , _in DWORD _in DWORD dwCreationFlagsdwCreationFlags, , _

7、in LPVOID _in LPVOID lpEnvironmentlpEnvironment, , _in LPCTSTR _in LPCTSTR lpCurrentDirectorylpCurrentDirectory, , _in LPSTARTUPINFO _in LPSTARTUPINFO lpStartupInfolpStartupInfo, , _out LPPROCESS_INFORMATION _out LPPROCESS_INFORMATION lpProcessInformationlpProcessInformation););For:分类信息From:新闻参数说明参数

8、说明plpApplicationNamelpApplicationName,要执行的应用程序名,可以包括结对路,要执行的应用程序名,可以包括结对路径和文件名,通常可以为径和文件名,通常可以为NULLNULL。plpCommandLinelpCommandLine,要执行的命令行。,要执行的命令行。plpProcessAttributeslpProcessAttributes,新进程的安全描述符。,新进程的安全描述符。plpThreadAttributeslpThreadAttributes,指定主线程的安全描述符。如果为,指定主线程的安全描述符。如果为NULLNULL,则使用默认的安全描述符。

9、,则使用默认的安全描述符。pbInheritHandlesbInheritHandles,指示新进程是否从调用进程处继承句柄。,指示新进程是否从调用进程处继承句柄。pdwCreationFlagsdwCreationFlags,指定附加的、用来控制优先类和进程创建,指定附加的、用来控制优先类和进程创建的标志。的标志。plpEnvironmentlpEnvironment,指向新进程的环境块。如果为,指向新进程的环境块。如果为NULLNULL,则使用,则使用调用调用CreateProcess()CreateProcess()函数的进程的环境。函数的进程的环境。For:分类信息From:新闻【例【

10、例7.1】p调用调用CreateProcess()CreateProcess()函数运行函数运行WindowsWindows计算器程序,并显示新进程的计算器程序,并显示新进程的IDID号,及其主号,及其主线程的线程的IdId号,代码如下:号,代码如下:#include stdafx.h#include stdafx.h#include #include int _tmain(int argc, _TCHAR* argv)int _tmain(int argc, _TCHAR* argv) char szCommandLine=calc.exe;char szCommandLine=calc.e

11、xe;STARTUPINFO si = sizeof(si);STARTUPINFO si = sizeof(si);PROCESS_INFORMATION pi;PROCESS_INFORMATION pi;si.dwFlags = STARTF_USESHOWWINDOW; / si.dwFlags = STARTF_USESHOWWINDOW; / 指定指定wShowWindowwShowWindow成员有效成员有效si.wShowWindow = TRUE; / si.wShowWindow = TRUE; / 显示新建进程的主窗口显示新建进程的主窗口 For:分类信息From:新闻接

12、上接上BOOL bRet = CreateProcess (NULL, / BOOL bRet = CreateProcess (NULL, / 不在此指定可执行文件的文件名不在此指定可执行文件的文件名szCommandLine, / szCommandLine, / 命令行参数命令行参数NULL,NULL,/ / 默认进程安全性默认进程安全性NULL,NULL,/ / 默认进程安全性默认进程安全性FALSE,FALSE,/ / 指定当前进程内句柄不可以被子进程继承指定当前进程内句柄不可以被子进程继承CREATE_NEW_CONSOLE, / CREATE_NEW_CONSOLE, / 为新进

13、程创建一个新的控制台窗口为新进程创建一个新的控制台窗口NULL,NULL,/ / 使用本进程的环境变量使用本进程的环境变量NULL,NULL,/ / 使用本进程的驱动器和目录使用本进程的驱动器和目录&si,&si,&pi) ; &pi) ; if(bRet)if(bRet)/ / 关掉不使用的句柄关掉不使用的句柄CloseHandle(pi.hThread);CloseHandle(pi.hThread);CloseHandle(pi.hProcess);CloseHandle(pi.hProcess);printf(printf(新进程的新进程的IDID号:号:%dn,pi.dwProces

14、sId);%dn,pi.dwProcessId);printf(printf(新进程的主线程新进程的主线程IDID号:号:%dn,pi.dwThreadId);%dn,pi.dwThreadId); system(pause);system(pause);return 0;return 0; For:分类信息From:新闻【例【例7.1】的运行结果】的运行结果For:分类信息From:新闻ShellExecute()函数函数HINSTANCEShellExecute(HINSTANCEShellExecute(HWNDhwnd,HWNDhwnd,/ / 指定显示用户界面和错误信息的窗口句柄指定

15、显示用户界面和错误信息的窗口句柄LPCTSTRlpOperation,LPCTSTRlpOperation, / / 对指定文件要执行的操作对指定文件要执行的操作LPCTSTRlpFile,LPCTSTRlpFile,/ / 要执行操作的文件或对象要执行操作的文件或对象LPCTSTRlpParameters,LPCTSTRlpParameters,/ / 指定传送给应用程序的参数指定传送给应用程序的参数LPCTSTRlpDirectory,LPCTSTRlpDirectory, / / 指定执行操作的工作目录指定执行操作的工作目录INTnShowCmdINTnShowCmd / / 指定应用程

16、序如何显示。指定应用程序如何显示。SW_HIDESW_HIDE表示隐藏窗口,表示隐藏窗口,SW_MAXIMIZESW_MAXIMIZE表示最大化窗口,表示最大化窗口,SW_MINIMIZESW_MINIMIZE表示最小化窗口,表示最小化窗口,SW_SHOWSW_SHOW表示在当前位置上以当前大小显示窗口,等等表示在当前位置上以当前大小显示窗口,等等););For:分类信息From:新闻pOperation参数的取值参数的取值取 值说 明edit打开一个文档文件进行编辑。如果参数lpFile指定的不是一个文档文件,则操作失败explore打开资源管理器查看指定文件所在的目录find从参数lpDi

17、rectory指定的目录开始搜索open打开指定的对象print打印指定的对象。如果参数lpFile指定的不是一个文档文件,则操作失败NULL执行默认的操作,通常执行open操作For:分类信息From:新闻【例【例7.2】【例【例7.27.2】调用】调用ShellExecute ()ShellExecute ()函数访问函数访问googlegoogle网站,网站,代码如下:代码如下:#include stdafx.h#include stdafx.h#include windows.h”#include windows.h”int _tmain(int argc, _TCHAR* argv)

18、int _tmain(int argc, _TCHAR* argv) ShellExecute(NULL, open, ShellExecute(NULL, open, http:/, , , SW_SHOW);http:/, , , SW_SHOW);return 0;return 0; For:分类信息From:新闻7.2.2枚举系统进程枚举系统进程1 1使用使用EnumProcesses()EnumProcesses()函数函数2 2使用进程快照使用进程快照For:分类信息From:新闻1使用使用EnumProcesses()函数函数BOOL WINAPI EnumProcesses(B

19、OOL WINAPI EnumProcesses( _out DWORD* pProcessIds, _out DWORD* pProcessIds, / / 用于接收进程标示符用于接收进程标示符列表的数组列表的数组 _in DWORD cb, _in DWORD cb,/ / 数组数组pProcessIdspProcessIds的大小,单的大小,单位是字节位是字节 _out DWORD* pBytesReturned/ _out DWORD* pBytesReturned/ 数组数组pProcessIdspProcessIds中中返回数据的大小,单位是字节返回数据的大小,单位是字节););p

20、如果函数执行成功,则返回一个非如果函数执行成功,则返回一个非0 0值;否则返回值;否则返回0 0。For:分类信息From:新闻【例【例7.3】p调用调用EnumProcess EnumProcess ()()函数枚举当前函数枚举当前WindowsWindows运行进程的标示符(运行进程的标示符(PIDPID),代码如下:),代码如下:#include stdafx.h#include stdafx.h#include #include #include #include #pragma comment(lib, Psapi.lib)#pragma comment(lib, Psapi.lib

21、)int _tmain(int argc, _TCHAR* argv)int _tmain(int argc, _TCHAR* argv) / / 用于接收返回的进程用于接收返回的进程IDID信息的数组信息的数组 DWORD dwProcs1024*2; DWORD dwProcs1024*2; DWORD dwNeeded; DWORD dwNeeded;/返回进程数组的大小返回进程数组的大小 / /枚举所有进程枚举所有进程IDID。For:分类信息From:新闻接上接上 if (!EnumProcesses( dwProcs, sizeof(dwProcs), &dwNeeded) if

22、(!EnumProcesses( dwProcs, sizeof(dwProcs), &dwNeeded) / /输出出错信息。输出出错信息。 printf(EnumProcesses failed (%d).n, GetLastError(); printf(EnumProcesses failed (%d).n, GetLastError(); else else DWORD dwProcCount = dwNeeded / sizeof(DWORD); DWORD dwProcCount = dwNeeded / sizeof(DWORD);for(int i=0; idwProcCou

23、nt; i+)for(int i=0; idwProcCount; i+) printf(PID: %dn,dwProcsi);printf(PID: %dn,dwProcsi); system(pause); system(pause);return 0;return 0; For:分类信息From:新闻【例【例7.3】的运行结果】的运行结果For:分类信息From:新闻2使用进程快照使用进程快照HANDLE WINAPI CreateToolhelp32Snapshot( HANDLE WINAPI CreateToolhelp32Snapshot( DWORD dwFlags, DWOR

24、D dwFlags, /指定快照中包含的对象指定快照中包含的对象 DWORD th32ProcessID DWORD th32ProcessID / / 指定获取进程快照的指定获取进程快照的PIDPID。如果为。如果为0 0,则获取当前系统进程列表,则获取当前系统进程列表););p如果函数执行成功,则返回进程快照的句柄;否则返如果函数执行成功,则返回进程快照的句柄;否则返回回INVALID_HANDLE_VALUEINVALID_HANDLE_VALUE。For:分类信息From:新闻Process32First()函数函数p调用调用Process32First()Process32First

25、()函数可以从进程函数可以从进程快照中获取第快照中获取第1 1个进程的信息,函数原型个进程的信息,函数原型如下:如下:BOOL WINAPI Process32First( BOOL WINAPI Process32First( HANDLE hSnapshot, HANDLE hSnapshot, / / 之前调用之前调用createtoolhelp32napshotcreatetoolhelp32napshot()()函数得到的进程快照句柄函数得到的进程快照句柄 LPPROCESSENTRY32 lppe LPPROCESSENTRY32 lppe / / 包含进程信息包含进程信息的结构体

26、的结构体););For:分类信息From:新闻结构体结构体LPPROCESSENTRY32pLANA_ENUMLANA_ENUM结构体中包含当前逻辑网络适配器的数量。当一个结构体中包含当前逻辑网络适配器的数量。当一个物理网络适配器绑定到一个网络协议时,就对应一个逻辑网物理网络适配器绑定到一个网络协议时,就对应一个逻辑网络适配器。执行络适配器。执行NCBNCB命令命令NCBENUMNCBENUM可以向可以向LANA_ENUMLANA_ENUM结构体中填结构体中填充逻辑网络适配器的个数和逻辑网络适配器编号,此时充逻辑网络适配器的个数和逻辑网络适配器编号,此时NCBNCB结结构体中的构体中的ncb_

27、bufferncb_buffer成员变量指向成员变量指向LANA_ENUMLANA_ENUM结构体。结构体。LANA_ENUMLANA_ENUM结构体的定义代码如下:结构体的定义代码如下:typedef typedef struct _LANA_ENUM struct _LANA_ENUM UCHAR length; UCHAR length; UCHAR lanaMAX_LANA; UCHAR lanaMAX_LANA;LANA_ENUM, *PLANA_ENUM;LANA_ENUM, *PLANA_ENUM;参数参数说明如下:说明如下:plengthlength,系统中包含的逻辑网络适配器

28、数量。,系统中包含的逻辑网络适配器数量。planaMAX_LANAlanaMAX_LANA,系统中包含的逻辑网络适配器编号数组。,系统中包含的逻辑网络适配器编号数组。For:分类信息From:新闻Process32Next()函数函数p调用调用Process32Next()Process32Next()函数可以从进程快照中获取下一函数可以从进程快照中获取下一个进程的信息,函数原型如下:个进程的信息,函数原型如下:BOOL WINAPI Process32Next( BOOL WINAPI Process32Next( HANDLE hSnapshot, HANDLE hSnapshot, 、/

29、 / 之前调用之前调用createtoolhelp32napshotcreatetoolhelp32napshot()()函数得到的进程快照句柄函数得到的进程快照句柄 LPPROCESSENTRY32 lppe / LPPROCESSENTRY32 lppe / 包含进程信息的结构体包含进程信息的结构体););p如果函数执行成功,则返回如果函数执行成功,则返回TRUETRUE;否则返回;否则返回FALSEFALSE。For:分类信息From:新闻【例【例7.4】p利用进程快照枚举当前利用进程快照枚举当前WindowsWindows运行进程的信息,代码如下:运行进程的信息,代码如下:#inclu

30、de stdafx.h#include stdafx.h#include windows.h#include windows.h#include tlhelp32.h#include tlhelp32.hint _tmain(int argc, _TCHAR* argv)int _tmain(int argc, _TCHAR* argv) PROCESSENTRY32 pe;PROCESSENTRY32 pe;/设置结构体设置结构体pepe的大小的大小pe.dwSize = sizeof(pe);pe.dwSize = sizeof(pe);/获取系统内进程的快照获取系统内进程的快照HANDL

31、E hProcessSnap = HANDLE hProcessSnap = :CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);:CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);if (hProcessSnap = INVALID_HANDLE_VALUE) if (hProcessSnap = INVALID_HANDLE_VALUE) printf(CreateToolhelp32Snapshot error.n);printf(CreateToolhelp32Snapshot error.n);r

32、eturn -1;return -1; For:分类信息From:新闻接上接上/遍历进程快照,显示每个进程的信息遍历进程快照,显示每个进程的信息BOOL bMore = :Process32First(hProcessSnap,&pe);BOOL bMore = :Process32First(hProcessSnap,&pe);while (bMore) while (bMore) printf(=n);printf(=n);printf(Process Nameprintf(Process Name:%sn,pe.szExeFile);%sn,pe.szExeFile);printf(PI

33、Dprintf(PID:%un,pe.th32ProcessID);%un,pe.th32ProcessID);printf(Number of Threadprintf(Number of Thread:%un,tThreads);%un,tThreads);printf(=n);printf(=n);bMore = :Process32Next(hProcessSnap,&pe);bMore = :Process32Next(hProcessSnap,&pe); /释放释放snapshotsnapshot对象对象:CloseHandle(hProcessSnap);:CloseHandle

34、(hProcessSnap);system(pause);system(pause);return 0;return 0; For:分类信息From:新闻4ASTAT结构体结构体pASTATASTAT结构体用于描述网络适配器的状态和名字信息,定义代结构体用于描述网络适配器的状态和名字信息,定义代码如下:码如下:typedef structtypedef struct ADAPTER_STATUS adapt; ADAPTER_STATUS adapt; NAME_BUFFER NameBuff30; NAME_BUFFER NameBuff30; ASTAT; ASTAT;p参数参数adapt

35、adapt表示网络适配器的状态信息,参数表示网络适配器的状态信息,参数NameBuffNameBuff表示网表示网络适配器中保存的本地网络名字信息。络适配器中保存的本地网络名字信息。For:分类信息From:新闻【例【例7.4】的运行结果】的运行结果For:分类信息From:新闻7.2.3终止终止进程进程p进程从主函数的第一行代码开始执行,直到主函数结进程从主函数的第一行代码开始执行,直到主函数结束时终止;也可以强制结束一个进程。当进程被终止束时终止;也可以强制结束一个进程。当进程被终止时,系统会进行下面的操作:时,系统会进行下面的操作:p进程中的所有线程都被标记为进程中的所有线程都被标记为“

36、终止终止”状态;状态;p分配给进程的所有资源都会被释放掉;分配给进程的所有资源都会被释放掉;p所有与该进程相关的内核对象都会被关闭;所有与该进程相关的内核对象都会被关闭;p从内存中移除该进程的代码;从内存中移除该进程的代码;p系统设置进程的退出代码;系统设置进程的退出代码;p将该进程对象设置为将该进程对象设置为“受信受信”(SigaledSigaled)状态。)状态。For:分类信息From:新闻GetExitCodeProcess()函数函数p调用调用GetExitCodeProcess()GetExitCodeProcess()函数可以获取进程的终止状态,函数原型函数可以获取进程的终止状态

37、,函数原型如下:如下:BOOL WINAPI GetExitCodeProcess(BOOL WINAPI GetExitCodeProcess( _inHANDLE hProcess, _inHANDLE hProcess,/ / 进程句柄进程句柄 _outLPDWORD lpExitCode _outLPDWORD lpExitCode/ / 用于接收进程的终止状态用于接收进程的终止状态););p如果函数执行成功,则返回如果函数执行成功,则返回TRUETRUE;否则返回;否则返回FALSEFALSE。当进程在运行中。当进程在运行中时,其终止状态为时,其终止状态为STILL_ACTIVEST

38、ILL_ACTIVE。当进程被终止时,其终止状态变成。当进程被终止时,其终止状态变成退出代码。退出代码。For:分类信息From:新闻ExitProcess()函数函数p在进程中调用在进程中调用ExitProcess()ExitProcess()函数终止其自身中所有的线程,函数函数终止其自身中所有的线程,函数原型如下:原型如下:VOID WINAPI ExitProcess(VOID WINAPI ExitProcess( _inUINT uExitCode _inUINT uExitCode/ / 退出代码退出代码););For:分类信息From:新闻TerminateProcess()函数

39、函数p调用调用TerminateProcess()TerminateProcess()函数可以终止指定的进程,函数原型如函数可以终止指定的进程,函数原型如下:下:BOOL WINAPI TerminateProcess(BOOL WINAPI TerminateProcess( _inHANDLE hProcess, _inHANDLE hProcess,/ / 要终止的进程句柄要终止的进程句柄 _inUINT uExitCode _inUINT uExitCode/退出代码退出代码););For:分类信息From:新闻7.3进程间通信进程间通信7.3.1 7.3.1 通过自定义消息进行通信通

40、过自定义消息进行通信7.3.2 7.3.2 通过通过管道管道进行通信进行通信7.3.3 7.3.3 使用互斥体使用互斥体7.3.4 7.3.4 通过共享内存进行通信通过共享内存进行通信For:分类信息From:新闻7.3.1通过自定义消息进行通信通过自定义消息进行通信1 1定义自定义消息的代码定义自定义消息的代码2 2发送消息发送消息3 3消息处理函数消息处理函数For:分类信息From:新闻1定义自定义消息的代码定义自定义消息的代码为了唯一标识自定义消息,需要为其定义一个消息代为了唯一标识自定义消息,需要为其定义一个消息代码。自定义的消息代码都比码。自定义的消息代码都比WM_USER要大,因

41、为要大,因为0WM_USER-1是保留给系统消息使用。可以使用下面是保留给系统消息使用。可以使用下面的代码定义一个自定义消息的代码定义一个自定义消息WM_MY_MESSAGE:#defineWM_MY_MESSAGE(WM_USER+100)For:分类信息From:新闻2发送消息发送消息p调用调用PostMessage()PostMessage()函数将消息放置到与创建指定窗口的进程函数将消息放置到与创建指定窗口的进程相关联的消息队列中,函数不需要等待接收方接受和处理消相关联的消息队列中,函数不需要等待接收方接受和处理消息就直接返回。函数原型如下:息就直接返回。函数原型如下:BOOL Pos

42、tMessage(BOOL PostMessage( HWND hWnd, HWND hWnd, / / 接收消息的窗口句柄,使用接收消息的窗口句柄,使用HWND_BROADCASTHWND_BROADCAST表示所有顶层窗口表示所有顶层窗口 UINT Msg, UINT Msg, / / 发送消息的代码发送消息的代码 WPARAM wParam, / WPARAM wParam, / 指定消息的附加信息指定消息的附加信息 LPARAM lParam / LPARAM lParam / 指定消息的附加信息指定消息的附加信息); ); For:分类信息From:新闻FindWindow()函数函

43、数HWND FindWindow( HWND FindWindow( LPCTSTR lpClassName, LPCTSTR lpClassName, /窗口类名,通常为窗口类名,通常为NULLNULL LPCTSTR lpWindowName LPCTSTR lpWindowName / / 要查找窗口的标题要查找窗口的标题); ); For:分类信息From:新闻3消息处理函数消息处理函数p在接收端需要设计一个消息处理函数,它的格式如下:在接收端需要设计一个消息处理函数,它的格式如下:LRESULTOnMyMsg(WPARAM wParam, LPARAM lParam)LRESULTO

44、nMyMsg(WPARAM wParam, LPARAM lParam) / / 处理代码处理代码return 0;return 0; p参数参数wParamwParam和和lParamlParam用于接收用于接收PostMessage()PostMessage()函数发送消息时指函数发送消息时指定的参数。定的参数。For:分类信息From:新闻将消息与其处理函数映射起来将消息与其处理函数映射起来p定义消息处理函数后还要将消息与其处理函数映射起来。在每个定义消息处理函数后还要将消息与其处理函数映射起来。在每个MFCMFC对话框对应的对话框对应的.cpp.cpp文件中,都在文件中,都在BEGIN

45、_MESSAGE_MAPBEGIN_MESSAGE_MAP宏和宏和END_MESSAGE_MAPEND_MESSAGE_MAP()()宏之间定义消息与其处理函数映射的,例如:宏之间定义消息与其处理函数映射的,例如:BEGIN_MESSAGE_MAP(CReceiverDlg, CDialog)BEGIN_MESSAGE_MAP(CReceiverDlg, CDialog)ON_WM_SYSCOMMAND()ON_WM_SYSCOMMAND()ON_WM_PAINT()ON_WM_PAINT()ON_WM_QUERYDRAGICON()ON_WM_QUERYDRAGICON()/AFX_MSG_

46、MAP/AFX_MSG_MAPEND_MESSAGE_MAP()END_MESSAGE_MAP()For:分类信息From:新闻BEGIN_MESSAGE_MAP宏宏pBEGIN_MESSAGE_MAPBEGIN_MESSAGE_MAP宏用于标识消息映射的开始,其原型如下:宏用于标识消息映射的开始,其原型如下:BEGIN_MESSAGE_MAP(theClass, baseClass )BEGIN_MESSAGE_MAP(theClass, baseClass )p参数参数theClasstheClass指定消息映射所属的类,通常是窗口类;参数指定消息映射所属的类,通常是窗口类;参数baseC

47、lassbaseClass指定参数指定参数theClasstheClass的基类。在的基类。在BEGIN_MESSAGE_MAPBEGIN_MESSAGE_MAP宏和宏和END_MESSAGE_MAPEND_MESSAGE_MAP()()宏之间添加一条宏之间添加一条ON_MESSAGEON_MESSAGE宏用于定义自定义消息及其处理函宏用于定义自定义消息及其处理函数的映射。数的映射。ON_MESSAGEON_MESSAGE宏的原型如下:宏的原型如下:ON_MESSAGE(message, memberFxn )ON_MESSAGE(message, memberFxn )p参数参数messag

48、emessage用于指定自定义消息的代码,参数用于指定自定义消息的代码,参数memberFxnmemberFxn指定消指定消息处理函数。息处理函数。For:分类信息From:新闻【例【例7.5】设计一个利用自定义消息实现进程间通信的例子。设计一个利用自定义消息实现进程间通信的例子。1 1设计发送端项目设计发送端项目2 2设计接收端项目设计接收端项目For:分类信息From:新闻1设计发送端项目设计发送端项目p创建一个基于对话框的创建一个基于对话框的MFCMFC应用程序应用程序SenderSender,定义自定,定义自定义消息义消息WM_MY_MESSAGEWM_MY_MESSAGE,代码如下:

49、,代码如下:#define WM_MY_MESSAGE (WM_USER+999)#define WM_MY_MESSAGE (WM_USER+999)For:分类信息From:新闻单击单击“发送消息发送消息”按钮的代码按钮的代码void CSenderDlg:OnBnClickedButtonSendmsg()void CSenderDlg:OnBnClickedButtonSendmsg() HWND hWnd = :FindWindow(NULL, Receiver); HWND hWnd = :FindWindow(NULL, Receiver); :PostMessage(hWnd,

50、WM_MY_MESSAGE, (WPARAM)999, NULL );:PostMessage(hWnd,WM_MY_MESSAGE, (WPARAM)999, NULL ); For:分类信息From:新闻2设计接收端项目设计接收端项目创建一个基于对话框的创建一个基于对话框的MFCMFC应用程序应用程序ReceiverReceiver,定义自定,定义自定义消息义消息WM_MY_MESSAGEWM_MY_MESSAGE,代码如下:,代码如下:#define WM_MY_MESSAGE (WM_USER+999)#define WM_MY_MESSAGE (WM_USER+999) p编写消息处

51、理函数编写消息处理函数OnMyMsg()OnMyMsg(),代码如下:,代码如下:LRESULT CReceiverDlg:OnMyMsg(WPARAM wParam, LPARAM lParam)LRESULT CReceiverDlg:OnMyMsg(WPARAM wParam, LPARAM lParam) char msg100;char msg100;sprintf(msg, %d, (int)wParam);sprintf(msg, %d, (int)wParam);MessageBox(msg, MessageBox(msg, 收到消息收到消息););return 0;retur

52、n 0; For:分类信息From:新闻添加自定义消息及其处理函数的映射添加自定义消息及其处理函数的映射BEGIN_MESSAGE_MAP(CReceiverDlg, CDialog)BEGIN_MESSAGE_MAP(CReceiverDlg, CDialog) ON_MESSAGE(WM_MY_MESSAGE, OnMyMsg) ON_MESSAGE(WM_MY_MESSAGE, OnMyMsg) / / 映射消息和处理函数映射消息和处理函数/AFX_MSG_MAP/AFX_MSG_MAPEND_MESSAGE_MAP()END_MESSAGE_MAP()For:分类信息From:新闻7.

53、3.2通过通过管道管道进行通信进行通信p管道(管道(PipePipe)是由标准输入输出流构成的进程链。一个进程的输)是由标准输入输出流构成的进程链。一个进程的输出直接作为下一个进程的输入。每个连接都是一个匿名管道。管出直接作为下一个进程的输入。每个连接都是一个匿名管道。管道包含一个写句柄和一个读句柄。一个进程使用写句柄向管道里道包含一个写句柄和一个读句柄。一个进程使用写句柄向管道里写入数据,另一个进程使用读句柄从管道中读取数据。写入数据,另一个进程使用读句柄从管道中读取数据。p调用调用CreatePipe()CreatePipe()函数可以创建管道,函数原型如下:函数可以创建管道,函数原型如下

54、:BOOL WINAPI CreatePipe(BOOL WINAPI CreatePipe( _out PHANDLE hReadPipe, _out PHANDLE hReadPipe,/ / 管道的读句柄管道的读句柄 _out PHANDLE hWritePipe, _out PHANDLE hWritePipe, _in LPSECURITY_ATTRIBUTES lpPipeAttributes, _in LPSECURITY_ATTRIBUTES lpPipeAttributes, _in DWORD nSize _in DWORD nSize););For:分类信息From:新闻

55、【例【例7.6】p设计一个利用管道实现进程间通信的例子。设计一个利用管道实现进程间通信的例子。p主进程主进程ServerServer的代码如下:的代码如下:#include stdafx.h#include stdafx.h#include #include int _tmain(int argc, _TCHAR* argv)int _tmain(int argc, _TCHAR* argv) HANDLE hRead; / HANDLE hRead; / 管道读句柄管道读句柄HANDLE hWrite; / HANDLE hWrite; / 管道写句柄管道写句柄SECURITY_ATTRIB

56、UTES sa; / SECURITY_ATTRIBUTES sa; / 设置管道属性设置管道属性sa.nLength = sizeof(SECURITY_ATTRIBUTES);sa.nLength = sizeof(SECURITY_ATTRIBUTES);sa.lpSecurityDescriptor = NULL;sa.lpSecurityDescriptor = NULL;sa.bInheritHandle = TRUE;sa.bInheritHandle = TRUE;/ / 指定管道句柄可以被子进程继承指定管道句柄可以被子进程继承BOOL bRet = CreatePipe(&h

57、Read, &hWrite, &sa, 0); / BOOL bRet = CreatePipe(&hRead, &hWrite, &sa, 0); / 创建匿名管道创建匿名管道if (bRet = TRUE)if (bRet = TRUE)printf(printf(成功创建匿名管道成功创建匿名管道!n);!n);elseelseprintf(printf(创建匿名管道失败创建匿名管道失败, ,错误代码错误代码:%dn, GetLastError(); :%dn, GetLastError(); For:分类信息From:新闻接上接上/ / 得到本进程的当前标准输出,以备将来恢复得到本进程的

58、当前标准输出,以备将来恢复HANDLE hTemp = GetStdHandle(STD_OUTPUT_HANDLE); HANDLE hTemp = GetStdHandle(STD_OUTPUT_HANDLE); / / 设置标准输出到匿名管道设置标准输出到匿名管道SetStdHandle(STD_OUTPUT_HANDLE, hWrite); SetStdHandle(STD_OUTPUT_HANDLE, hWrite); STARTUPINFO si; STARTUPINFO si; GetStartupInfo(&si); / GetStartupInfo(&si); / 获取本进程

59、的获取本进程的STARTUPINFOSTARTUPINFO结构信息,包括标准设备的结构信息,包括标准设备的句柄句柄PROCESS_INFORMATION pi; PROCESS_INFORMATION pi; / / 创建客户端子进程创建客户端子进程Client.exeClient.exe,它会继承父进程的标准输出,因此,它会继承父进程的标准输出,因此Client.exeClient.exe的标准输出是到的标准输出是到hWritehWrite管道的管道的bRet = CreateProcess(NULL, Client.exe, NULL, NULL, TRUE, NULL, NULL, bR

60、et = CreateProcess(NULL, Client.exe, NULL, NULL, TRUE, NULL, NULL, NULL, &si, &pi); NULL, &si, &pi); SetStdHandle(STD_OUTPUT_HANDLE, hTemp); / SetStdHandle(STD_OUTPUT_HANDLE, hTemp); / 恢复本进程的标准输出恢复本进程的标准输出if (bRet = TRUE) / if (bRet = TRUE) / 输入信息输入信息printf(printf(成功创建子进程成功创建子进程!n); !n); elseelsepri

61、ntf(printf(创建子进程失败创建子进程失败, ,错误代码错误代码:%dn, GetLastError(); :%dn, GetLastError(); For:分类信息From:新闻接上接上/ / 读管道直至管道关闭读管道直至管道关闭char ReadBuf100;char ReadBuf100;DWORD ReadNum;DWORD ReadNum;/ / 循环从管道中读取数据循环从管道中读取数据while (ReadFile(hRead, ReadBuf, 100, &ReadNum, NULL) while (ReadFile(hRead, ReadBuf, 100, &Read

62、Num, NULL) ReadBufReadNum = 0;ReadBufReadNum = 0;printf(printf(从管道读取从管道读取%d%d字节数据:【字节数据:【%s%s】n, ReadNum, ReadBuf);n, ReadNum, ReadBuf); if (GetLastError() = ERROR_BROKEN_PIPE) / if (GetLastError() = ERROR_BROKEN_PIPE) / 输出信息输出信息printf(printf(管道被子进程关闭管道被子进程关闭n);n);elseelseprintf(printf(读数据错误读数据错误, ,

63、错误代码错误代码:%dn, GetLastError(); :%dn, GetLastError(); return 0;return 0; For:分类信息From:新闻子进程子进程Client的代码的代码#include stdafx.h#include stdafx.h#include #include #include #include using namespace std;using namespace std;int _tmain(int argc, _TCHAR* argv)int _tmain(int argc, _TCHAR* argv) for (int i = 0; i

64、 10; i+) / for (int i = 0; i 10; i+) / 发送一些数据到标准输出和标准错误发送一些数据到标准输出和标准错误 printf(i = %d; , i); / printf(i = %d; , i); / 打印提示打印提示cout cout 标准输出:标准输出: i endl; / i endl; / 打印到标准输出打印到标准输出cerr cerr 标准错误标准错误: i endl; / : i endl; / 打印到标准错误打印到标准错误 return 0;return 0; For:分类信息From:新闻【例【例7.6】的运行结果】的运行结果For:分类信息F

65、rom:新闻7.3.3使用互斥体使用互斥体HANDLE WINAPI CreateMutex(HANDLE WINAPI CreateMutex( _in LPSECURITY_ATTRIBUTES lpMutexAttributes, _in LPSECURITY_ATTRIBUTES lpMutexAttributes,/ / 互斥体对象的安全属性,如果为互斥体对象的安全属性,如果为NULLZNULLZ,则互斥体对象不能被子进,则互斥体对象不能被子进程继承程继承 _in BOOL bInitialOwner, _in BOOL bInitialOwner, / / 初始化互斥对象的所有初始

66、化互斥对象的所有者者 _in LPCTSTR lpName _in LPCTSTR lpName/ / 指定互斥对象的名字指定互斥对象的名字););如果在不同进程间使用互斥体,则该互斥体对象是全局的。全局互斥如果在不同进程间使用互斥体,则该互斥体对象是全局的。全局互斥体对象的名字必须以体对象的名字必须以“GlobalGlobal”为前缀,而本地互斥体对象的名为前缀,而本地互斥体对象的名字则以字则以“LocalLocal”为前缀。为前缀。For:分类信息From:新闻【例【例7.7】p设计一个利用互斥体防止运行一个应用程序的多个实例的例子设计一个利用互斥体防止运行一个应用程序的多个实例的例子Mu

67、texMutex,代码如下:,代码如下:int _tmain(int argc, _TCHAR* argv)int _tmain(int argc, _TCHAR* argv) CreateMutex(NULL,TRUE, GlobalMyMutex001); CreateMutex(NULL,TRUE, GlobalMyMutex001); if(GetLastError()=ERROR_ALREADY_EXISTS) if(GetLastError()=ERROR_ALREADY_EXISTS) printf(printf(应用程序已经运行应用程序已经运行!n);!n);exit(0);

68、exit(0); printf(printf(已进入应用程序已进入应用程序.n);.n);system(pause);system(pause);return 0;return 0; For:分类信息From:新闻第第1次运行次运行Mutex.exe的结果的结果For:分类信息From:新闻7.3.4通过共享内存进行通信通过共享内存进行通信p每个每个WindowsWindows进程都有其私有的内存空间。任何进程都不能修改其进程都有其私有的内存空间。任何进程都不能修改其他进程的内存空间,包括变量和对象等。但是多个进程间可以通他进程的内存空间,包括变量和对象等。但是多个进程间可以通过一块共享内存进

69、行通信。共享内存是允许多个进程同时访问的过一块共享内存进行通信。共享内存是允许多个进程同时访问的内存,不同的进程可以通过共享内存进行通讯,也可以避免在不内存,不同的进程可以通过共享内存进行通讯,也可以避免在不同的程序中保存多余的数据备份。通常可以使用同的程序中保存多余的数据备份。通常可以使用内存内存映射文件实映射文件实现共享内存,用现共享内存,用内存内存映射文件是由一个文件到一块内存的映射。映射文件是由一个文件到一块内存的映射。内存映射文件与虚拟内存有些类似,通过内存映射文件可以保留内存映射文件与虚拟内存有些类似,通过内存映射文件可以保留一个地址空间的内存区域,同时将物理存储器提交给此区域,内

70、一个地址空间的内存区域,同时将物理存储器提交给此区域,内存文件映射的物理存储器来自一个已经存在于磁盘上的文件,而存文件映射的物理存储器来自一个已经存在于磁盘上的文件,而且在对该文件进行操作之前必须首先对文件进行映射。使用内存且在对该文件进行操作之前必须首先对文件进行映射。使用内存映射文件处理存储于磁盘上的文件时,将不必再对文件执行过多映射文件处理存储于磁盘上的文件时,将不必再对文件执行过多的的I/OI/O操作,因此,内存映射文件在处理大数据量的文件时能起到操作,因此,内存映射文件在处理大数据量的文件时能起到相当重要的作用。相当重要的作用。For:分类信息From:新闻CreateFileMap

71、ping()函数函数HANDLE CreateFileMapping(HANDLE CreateFileMapping( HANDLE hFile, HANDLE hFile, LPSECURITY_ATTRIBUTES lpFileMappingAttributes, LPSECURITY_ATTRIBUTES lpFileMappingAttributes, DWORD flProtect, DWORD flProtect, DWORD dwMaximumSizeHigh, DWORD dwMaximumSizeHigh, DWORD dwMaximumSizeLow, DWORD dwM

72、aximumSizeLow, LPCTSTR lpName LPCTSTR lpName ););For:分类信息From:新闻参数说明参数说明phFilehFile:创建映射对象的文件句柄,如果使用:创建映射对象的文件句柄,如果使用INVALID_HANDLE_VALUEINVALID_HANDLE_VALUE,则在物理内存中创建映射对象。,则在物理内存中创建映射对象。plpFileMappingAttributeslpFileMappingAttributes:被忽略,必须为:被忽略,必须为NULLNULL。pflProtectflProtect,文件视图的保护方式。,文件视图的保护方式。

73、pdwMaximumSizeHighdwMaximumSizeHigh,指定文件映射对象最大大小的高,指定文件映射对象最大大小的高3232位。位。pdwMaximumSizeLowdwMaximumSizeLow,指定文件映射对象最大大小的低,指定文件映射对象最大大小的低3232位。位。plpNamelpName,映射对象的名字,如果是全局映射对象,则名,映射对象的名字,如果是全局映射对象,则名字可以以字可以以“GlobalGlobal”前缀开始。前缀开始。For:分类信息From:新闻MapViewOfFile()函数函数p调用调用MapViewOfFile()MapViewOfFile()

74、函数可以将指定的文件视图映射到调用进程函数可以将指定的文件视图映射到调用进程的地址空间,函数原型如下:的地址空间,函数原型如下:LPVOID MapViewOfFile( LPVOID MapViewOfFile( HANDLE hFileMappingObject, / HANDLE hFileMappingObject, /文件映射对象的句柄,通常由文件映射对象的句柄,通常由CreateFileMappingCreateFileMapping()()函数返回函数返回 DWORD dwDesiredAccess, DWORD dwDesiredAccess, / / 对文件视图的访问类型对文

75、件视图的访问类型 DWORD dwFileOffsetHigh, / DWORD dwFileOffsetHigh, / 指定开始映射的文件偏移量的高指定开始映射的文件偏移量的高3232位位 DWORD dwFileOffsetLow, / DWORD dwFileOffsetLow, / 指定开始映射的文件偏移量的低指定开始映射的文件偏移量的低3232位位 DWORD dwNumberOfBytesToMap / DWORD dwNumberOfBytesToMap / 指定文件映射的字节数。如果为指定文件映射的字节数。如果为0 0,则映射整个文件。,则映射整个文件。););For:分类信息

76、From:新闻OpenFileMapping()函数函数HANDLE WINAPI OpenFileMapping(HANDLE WINAPI OpenFileMapping( _in DWORD dwDesiredAccess,/ _in DWORD dwDesiredAccess,/ 访问权限访问权限 _in BOOL bInheritHandle, _in BOOL bInheritHandle,/ / 指定子进程是否指定子进程是否可以继承句柄可以继承句柄 _in LPCTSTR lpName _in LPCTSTR lpName/指定要打开指定的文件映指定要打开指定的文件映射对象的名字

77、射对象的名字););p如果函数执行成功,则返回打开指定的文件映射对象句柄;否则如果函数执行成功,则返回打开指定的文件映射对象句柄;否则返回返回NULLNULL。可以调用。可以调用GetLastError()GetLastError()函数获取错误代码。函数获取错误代码。For:分类信息From:新闻UnmapViewOfFile()函数函数p调用调用UnmapViewOfFile()UnmapViewOfFile()函数可以从调用进程的地址空间中解除文件视图函数可以从调用进程的地址空间中解除文件视图的映射。函数原型如下:的映射。函数原型如下:BOOL UnmapViewOfFile( BOOL

78、 UnmapViewOfFile( LPCVOID lpBaseAddress LPCVOID lpBaseAddress / / 要解除的文件视图映射的基地址要解除的文件视图映射的基地址););For:分类信息From:新闻【例【例7.8】p计一个创建文件映射对象,并向映射视图中写入数据的例子计一个创建文件映射对象,并向映射视图中写入数据的例子Process1Process1,代码如下:,代码如下:#include stdafx.h#include stdafx.h#include #include #include #include #include #include #define BU

79、F_SIZE 256#define BUF_SIZE 256/ / 共享内存的大小共享内存的大小TCHAR szName=TEXT(GlobalMyFileMappingObject);TCHAR szName=TEXT(GlobalMyFileMappingObject);/文件映射对象的名字文件映射对象的名字TCHAR szMsg=TEXT(Message from process1); / TCHAR szMsg=TEXT(Message from process1); / 向共享内存中写入的数据向共享内存中写入的数据int _tmain(int argc, _TCHAR* argv)i

80、nt _tmain(int argc, _TCHAR* argv) HANDLE hMapFile; HANDLE hMapFile; LPCTSTR pBuf LPCTSTR pBuf; ;For:分类信息From:新闻接上接上/ / 创建文件映射对象创建文件映射对象 hMapFile = CreateFileMapping( hMapFile = CreateFileMapping( INVALID_HANDLE_VALUE, / INVALID_HANDLE_VALUE, / 使用页文件使用页文件 NULL, NULL, PAGE_READWRITE, / PAGE_READWRITE,

81、 / 可读写可读写 0, 0, BUF_SIZE, / BUF_SIZE, / 文件映射对象的大小文件映射对象的大小 szName); / szName); / 文件映射对象的名字文件映射对象的名字 if (hMapFile = NULL) if (hMapFile = NULL) printf(Could not create file mapping object (%d).n, printf(Could not create file mapping object (%d).n, GetLastError(); GetLastError(); return 1; return 1; Fo

82、r:分类信息From:新闻接上接上 / / 将指定的文件视图映射到调用进程的地址空间,得到的将指定的文件视图映射到调用进程的地址空间,得到的pBufpBuf地址就是共享内存的开始地址,共地址就是共享内存的开始地址,共享内存的大小为享内存的大小为BUF_SIZEBUF_SIZE pBuf = (LPTSTR) MapViewOfFile(hMapFile, / pBuf = (LPTSTR) MapViewOfFile(hMapFile, / 映射对象的句柄映射对象的句柄 FILE_MAP_ALL_ACCESS, / FILE_MAP_ALL_ACCESS, / 可读写可读写 0, 0, 0,

83、0, BUF_SIZE); BUF_SIZE); if (pBuf = NULL) if (pBuf = NULL) printf(Could not map view of file (%d).n, printf(Could not map view of file (%d).n, GetLastError(); GetLastError(); return 2; return 2; / / 向共享内存中写入数据向共享内存中写入数据 CopyMemory(PVOID)pBuf, szMsg, strlen(szMsg); CopyMemory(PVOID)pBuf, szMsg, strle

84、n(szMsg); system(pause); / system(pause); / 等待其他进程从共享内存中读取数据等待其他进程从共享内存中读取数据 / / 从调用进程的地址空间中解除文件视图的映射从调用进程的地址空间中解除文件视图的映射 UnmapViewOfFile(pBuf); UnmapViewOfFile(pBuf); / / 关闭映射对象的句柄关闭映射对象的句柄 CloseHandle(hMapFile); CloseHandle(hMapFile);return 0;return 0; For:分类信息From:新闻设计一个从设计一个从Process1创建的映射视图中读取数据

85、的例子创建的映射视图中读取数据的例子Process2#include stdafx.h#include stdafx.h#include #include #include #include #include #include #define BUF_SIZE 256/ #define BUF_SIZE 256/ 共享内存的大小共享内存的大小TCHAR szName=TEXT(GlobalMyFileMappingObject);/TCHAR szName=TEXT(GlobalMyFileMappingObject);/文件映射对象的名字文件映射对象的名字int _tmain(int arg

86、c, _TCHAR* argv)int _tmain(int argc, _TCHAR* argv) HANDLE hMapFile; HANDLE hMapFile; LPCTSTR pBuf; LPCTSTR pBuf; / / 打开例打开例.8.8中创建的文件映射对象中创建的文件映射对象 hMapFile = OpenFileMapping( hMapFile = OpenFileMapping( FILE_MAP_ALL_ACCESS, / FILE_MAP_ALL_ACCESS, / 可读写可读写 FALSE, / FALSE, / 指定子进程不继承句柄指定子进程不继承句柄 szNa

87、me); / szName); / 指定要打开指定的文件映射对象的指定要打开指定的文件映射对象的名字名字 For:分类信息From:新闻接上接上 if (hMapFile = NULL) if (hMapFile = NULL) printf(Could not open file mapping object (%d).n, printf(Could not open file mapping object (%d).n, GetLastError(); GetLastError(); system(pause); system(pause); return 1; return 1; / /

88、 将指定的文件视图映射到调用进程的地址空间,得到的将指定的文件视图映射到调用进程的地址空间,得到的pBufpBuf地址就是共享内存的开始地址,共享内存的大小为地址就是共享内存的开始地址,共享内存的大小为BUF_SIZEBUF_SIZE pBuf = (LPTSTR) MapViewOfFile(hMapFile, / pBuf = (LPTSTR) MapViewOfFile(hMapFile, / 映射对象的句柄映射对象的句柄 FILE_MAP_ALL_ACCESS, / FILE_MAP_ALL_ACCESS, /可读写可读写 0, 0, 0, 0, BUF_SIZE); BUF_SIZE

89、); For:分类信息From:新闻接上接上 if (pBuf = NULL) if (pBuf = NULL) printf(Could not map view of file (%d).n, printf(Could not map view of file (%d).n, GetLastError(); GetLastError(); system(pause); system(pause); return 2; return 2; / / 打印共享内存中的数据打印共享内存中的数据 printf(Read from Map file : %snn, pBuf); printf(Read from Map file : %snn, pBuf); / / 从调用进程的地址空间中解除文件视图的映射从调用进程的地址空间中解除文件视图的映射 UnmapViewOfFile(pBuf); UnmapViewOfFile(pBuf); / / 关闭映射对象的句柄关闭映射对象的句柄 CloseHandle(hMapFile); CloseHandle(hMapFile); system(pause); system(pause);return 0;return 0; For:分类信息From:新闻Process2的运行结果的运行结果

展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 办公文档 > 工作计划

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号