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

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





  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值