进程间通信(1):匿名管道

来源:互联网 发布:linux网络命令 编辑:程序博客网 时间:2024/05/18 02:47

进程可以理解为一个独立的程序和其支配的内存空间,是程序运行的实体。进程拥有独立的内存空间,在两个进程间实现数据共享相对线程要困难一些。在这系列文章中,对不同的进程间数据共享方式进行说明,并通过C++实例进行实现讲解。


搜索一下网上进程间通信方式,比较夸张的是说有“十一”种方法,方法虽多,但是基本原理都是相通的,一个东西不同包装而已。其实掌握主要方法,既可以应对日常的工作。本系列文章从常用方法说起,争取覆盖所有见得到的方法。


管道通信的方式,是通过建立管道文件,实现进程间的信息传输通道。

 

管道是常用的进程间通信方式,管道主要分为匿名管道和命名管道两种。

 

这里首先讲解匿名管道,余下的在后续文章中介绍。(这里插一句, “匿”的拼音为nin,写到这里要感慨一下自己的语文,学的还是有瑕疵。)

 

管道信息传输遵循“先入先出”(FIFO)原则,即先写入管道的信息,会被首先读取出来。

 

匿名管道(“Anonymous Pipe”)是管道中的一种,该类管道在使用过程中,有比较多的限制。匿名管道只能用于父子进程间的通信,这里我们定义父进程为程序的第一次入口,子进程是在父进程中,通过程序产生的进程,二者拥有了天然的亲缘关系。这种亲缘关系使得通信参数的传递更加便捷,可通过“标准读句柄”和“标准写句柄”在进程中获得管道文件的标识,从而实现通信。

 

结合例子进行讲解,例程如下。由于子进程必须由父进程创建,为了简化程序,这里将父进程和子进程写于同一主函数中,通过参数决定父子进程代码的不同。

 

父进程无输入参数,父进程首先创建管道,匿名管道传输中的管道必须由父进程创建,创建管道后启动子进程,在子进程的命令行中添加参数,实现进程的功能控制。在创建进程后,向管道写入数据,程序暂停,等待子进程读取。

 

子进程创建后,通过标准输入句柄获取管道文件,并从中读取父进程写入的信息,实现匿名管道通信。

 

注:此例为Windows平台下编程实例,应用windows平台封装的管道API实现通信。


文章中示例代码的完整工程文件可在http://download.csdn.net/detail/ezhchai/9895267中下载。

#include "stdafx.h"#include <windows.h>#include <iostream>using namespace std;int main(int argc, char* argv[]){if (argc > 1){/* * * 子进程 * * */cout << "Child Process" << endl;/* * 接收管道数据,并显示 * */CHAR szBuffer[16]{ 0 };ReadFile(GetStdHandle(STD_INPUT_HANDLE), szBuffer, sizeof(szBuffer), nullptr, nullptr);cout << szBuffer << endl;}else{/* * * 父进程 * * */cout << "Parent Process" << endl;HANDLE hPipeW = NULL, hPipeR = NULL; //读管道句柄和写管道句柄//安全性结构SECURITY_ATTRIBUTES sa{ 0 };sa.nLength = sizeof(sa);sa.bInheritHandle = TRUE;//填充安全性结构使句柄被继承 // 创建匿名管道if (!CreatePipe(&hPipeR, &hPipeW, &sa, 0)){cout << "Create pipe failed! Processs return!" << endl;return 1;}// 进程信息结构体PROCESS_INFORMATION pi{ 0 };// 进程启动窗体信息结构体STARTUPINFOA si{ 0 };si.cb = sizeof(si);si.hStdInput = hPipeR;si.dwFlags = STARTF_USESTDHANDLES;// 为子进程命令行添加参数char param[1024];sprintf_s(param, "%s %s", argv[0], "test"); // 创建子进程if (!CreateProcessA(nullptr, param, nullptr, nullptr, TRUE, CREATE_NEW_CONSOLE, nullptr, nullptr, &si, &pi)){CloseHandle(hPipeR);CloseHandle(hPipeW);cout << "Create child process failed! Process return!" << endl;return 2;}// 写管道数据WriteFile(hPipeW, "ezhchai", 7, nullptr, nullptr);}system("pause");return 0;}





原创粉丝点击