进程间通信

进程间通信

剪切板:是系统维护管理的一块内存区域,当在一个进程中复制数据时,是将这个数据放到该内存区域中,当在另一个进程中粘贴数据时,是从该内存区域中取出数据,然后显示在窗口上

Bool OpenClipboard(): 打开剪切板

Bool EmptyClipboard():清空剪切板,只有清空剪切板后,打开剪切板的窗口才拥有剪切板

HGLOBAL GlobalAlloc(UINT uFlags , SIZE_T dwBytes):从堆上分配指定数目的字节数

LPVOID GlobalLock(HANDLE hMem): 返回该内存块指针,对全局内存对象进行加锁

Bool GlobalUnlock(HANDLE hMem): 对加锁内存进行解锁

HANDLE SetClipboardData(UINT uFormat,HANDLE hMem);向剪切板中放置数据

Bool CloseClipboard(HANDLE hMem): 关闭剪切板,否则其他进程无法打开剪切板

BOOL IsClipboardFormatAvaliable(UINT format):检测剪切板上时候包含了参数format指定的特定格式的数据

HANDLE GetClipboardData(UINT uFormat);根据参数指定的格式,返回以指定格式存在的剪切板对象的句柄

剪切板是系统提供的,所有进程都可以访问它

匿名管道:是一个未命名的,单向管道,通常在一个父进程和子进程之间传输数据。只能实现本地机器上两个进程间的通信,而不能实现跨网络的通信

BOOL CreatePipe(PHANDLE hReadPipe, //返回管道的读取句柄

PHANDLE hWritePipe,//返回管道的写入句柄

LPSECURITY_ATTRIBUTES lpPopeAttributes, //检测返回的句柄能不能被子进程继承

DWORD nSize//指定管的大小,0为默认的缓冲区大小

)

typedef struct _SECURITY_ATTRUBUTES

{

DWORD nLength,//结构体的大小

LPVOID lpSecutiryDescriptor,//指向安全描述符的指针

BOOL bInheritHandle,//指定所返回的句柄能否被新进程所继承,true是可以

} SECURITY_ATTRIBUTES,*PSSECURITY_ATTRIBUTES;

BOOL CreateProcess

(

LPCTSTR lpApplicationName,//指定可执行程序的名称,要加上扩展名

LPTSTR lpCommandLine,//传递给新进程的命令行参数

LPSECURITY_ATTRIBUTES lpProcessAttributes,//设置新进程的安全性

LPSECURITY_ATTRIBUTES lpThreadAttributes,//设置新新线程的安全性

BOOL bInheritHandle ,//指定新创建的子进程能否继承父进程的对象句柄

DOWORD dwCreationFlags,//进程优先级和进程创建的标记

LPVOID lpEnvironment,//指向环境块的指针

LPCTSTR lpCurrentDirectory,//子进程当前的路径,必须是完整的路径

LPSTARTUPINFO lpStartupInfo,//指定新进程的窗口如何显示

LPPROCESS_INFOMATION lpProcessInformation,,作为返回值使用

)

如果在lpApplicationName中指定可执行文件名,系统将会在当前目录下查找该可执行文件,如果没找到,则返回失败

如果在lpCommandLine中指定可执行文件名,系统会按一定顺序查找文件,如果没找到,则返回失败

如果在lpApplicationName参数中没有指定文件扩展名,此函数不会自动添加.exe扩展名

如果在lpCommandLine参数中没有指定文件扩展名,此函数会自动添加.exe扩展名

通常,我们把可执行文件名和命令行参数都传递给lpCommandLine

调用CreateProcess创建新进程时,系统将为新进程创建一个进程内核对象和线程内核对象

Typedef struct _STARTUPINFO

(

DWORD cb;//结构体的大小

LPTSTR lpReserved;

LPTSTR lpDesktop;

LPTSTR lpTitle;

DWORD dwX;

DWORD dwY;

DWORD dwXSize;

DWORD dwYSize;

DWORD dwXCountChars;

DWORD dwYCountChars;

DWORD dwFillAttribute;

DWORD dwFlags;//

DWORD wShowWindow;

DWORD cbreserved2;

HANDLE hStdInput;//输入

HANDLE hStdOutput;/输出

HANDLE hStdError;//错误句柄

)STARTUPINFO,*LPSTARTUPINFO;

Typedef struct _PROCESS_INFORMATION

{

HANDLE hProcess;//新创建的进程句柄

HANDLE hThread;//新创建的线程句柄

DWORD dwProcessId;//全局进程的标志符

DWORD dwThreadId;//全局线程的标志符

}PROCESS_INFORMATION;

当启动一个进程时,系统会为此进程分配一个标识符,同时这个进程中的线程也会被分配一个标志符,在一个进程运行时,该进程的标识符和线程的标识符是唯一的。

如果一个函数调用依赖于进程的标识符或线程的标志符,那么要确保该进程是否处于运行状态。因为当进程停止运行时,该进程的标志符和其线程的标志符,可能会被系统分配给另一个进程和线程使用

创建一个新进程时,系统会为该进程建立一个进程内核对象和线程内核对象,初始化这两个内核对象的使用计数为1,在CreateProcess函数返回之前,它将打开创建的进程对象和线程对象,此时每个对象的使用计数变为2。如果父进程中不需要使用进程内核对象和线程内核对象,则可以调用CloseHandle关闭它们

因为匿名管道没有名称,所以只能在父进程中调用CreateProcess函数创建子进程时,将管道的读写句柄传给子进程

利用匿名管道还可以实现在同一个进程内读取和写入数据

命名管道不仅可以在本地上实现两个进程间的通信,还可以跨网络实现两个进程间的通信

命名管道作为一种网络编程方案,实际上建立了一个客户机/服务器通信体系,并在其中可靠地传输数据,采用命名管道文件系统(Nameed Pipe File System,NPFS)接口,因此客户机和服务器可利用标准的Win32文件系统函数来进行数据的收发

命名管道的服务器和客户机的区别在于,服务器是唯一一个有权创建命名管道的进程,只有它能够接受管道客户机的连接请求,而客户机只能同一个现成的命名管道服务器建立连接

原文地址:https://www.cnblogs.com/xiaoxiaocaicai/p/3595335.html