匿名管道

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

BOOL CreatePipe(

PHANDLE hReadPipe,                       // read handle

PHANDLE hWritePipe,                      // write handle

LPSECURITY_ATTRIBUTES lpPipeAttributes,  // security attributes

DWORD nSize                              // pipe size

);

CreateProcess 创建进程

创建父进程:

a. CreatePipe:其中第三个参数代表安全属性结构体SECURITY_ATTRIBUTES的指针,在前几章的运用中,都是运用了NULL,代表返回的安全句柄不可以被子进程所继承。但在本运用中,涉及到的是匿名管道。匿名管道就是父子进程之间的通信,所以结构体必须设置相应的值。子进程要想获得匿名管道的读写句柄,只能从父进程继承而来。一旦子进程有了继承而来的读写句柄,就可以和父进程进行通信了。对于机构体SECURITY_ATTRIBUTES,最重要的是第三个参数bInheritHandle,表示Specifies whether the returned handle is inherited when a new process is created. If this member is TRUE, the new process inherits the handle.

b. CreateProcess:如果创建管道成功,则创建子进程,并将管道的读写句柄传递给子进程。

1.MFC单文档程序菜单中增加创建管道,读取数据,写入数据三项

2.View类中增加成员变量

3.  CreateProcess

倒数第三个参数 [in] Pointer to a STARTUPINFO structure that specifies how the main window for the new process should appear 指向STARTUPINFO结构体的一个指针,用来指定新的进程它的主窗口如何出现

最后一个参数指向PROCESS_INFORMATION结构体的一个指针的返回值,用来接收新的进程的标识信息

PROCESS_INFORMATION

The PROCESS_INFORMATION structure is filled in by the CreateProcess function with information

about a newly created process and its primary thread.

typedef struct _PROCESS_INFORMATION {

HANDLE hProcess;

HANDLE hThread;

DWORD dwProcessId;

DWORD dwThreadId;

} PROCESS_INFORMATION;

Members

hProcess //新创建进程的句柄

A handle to the newly created process. The handle is used to specify the process in all

functions that perform operations on the process object.

hThread //新创建进程主线程的句柄

A handle to the primary thread of the newly created process. The handle is used to specify

the thread in all functions that perform operations on the thread object.

dwProcessId //全局进程标识符,如果进程结束操作系统可能会将标识分配给其他进程,我们调用标识的时候要确保进程在运行

A global process identifier that can be used to identify a process. The value is valid from the time the process is created until the time the process is terminated.

dwThreadId //全局线程标识符

A global thread identifiers that can be used to identify a thread. The value is valid from the

time the thread is created until the time the thread is terminated.

创建匿名管道具体代码:

SECURITY_ATTRIBUTES sa;

//总共就三个参数

sa.bInheritHandle=TRUE; //表示可被子进程所继承

sa.lpSecurityDescriptor=NULL; //安全描述符号一般都设置成NULL,即默认描述符

sa.nLength=sizeof(SECURITY_ATTRIBUTES); //管道长度

if(!CreatePipe(&hRead,&hWrite,&sa,0))

{

MessageBox("创建匿名函数失败!");

return;

}

//管道创建成功后,接着创建子进程,并将读写句柄传递给子进程

STARTUPINFO sui;

PROCESS_INFORMATION pi;

//调用ZeroMemory方法将该结构体中的所有成员都置为0,这是因为这个结构体的成员很多,如果开始的时候没有置为0的话,那它的值是随机的,将这样的结构体传给CreateProcess,可能会影响到执行的结果。

ZeroMemory(&sui,sizeof(STARTUPINFO));

sui.cb=sizeof(STARTUPINFO); //设置结构体的大小

sui.dwFlags=STARTF_USESTDHANDLES; //该标识表示标准输入句柄,标准输出句柄和错误句柄是有用的

sui.hStdInput=hRead; //将子进程的输入句柄设置成父进程的读句柄

sui.hStdOutput=hWrite; //将子进程的输出句柄设置成父进程的写句柄

sui.hStdError=GetStdHandle(STD_ERROR_HANDLE); //得到标准错误句柄,是父进程的错误句柄,该行代码在本程序中没有实际的用途意义

//因为是匿名管道,是没有名称的管道,只有通过CreateProcess由上而下的传递管道操作句柄。

if(!CreateProcess("..\\Child\\Debug\\Child.exe",NULL,NULL,NULL,

TRUE,0,NULL,NULL,&sui,π))

{

MessageBox("创建子进程失败!");

CloseHandle(hRead);

CloseHandle(hWrite);

//避免在析构函数中再次关闭,析构函数采用:

//if(hRead) CloseHandle(hRead)

hRead=NULL;

hWrite=NULL;

return;

}

else

{

//创建一个新的进程的时候,系统会创建一个进程内核对象和一个线程内核对象,内核对象都有一个使用基数,初始调用的时候,都设置为1。在CreateProcess返回之前,该函数打开进程和线程的内核对象,并将进程相关的句柄放置到结构体PROCESS_INFORMATION的hProcess和hThread中,当Process在内部打开这些对象的时候,使得每个对象的使用基数增加到2了。如果在父进程中不需要使用这两个句柄,就将这个句柄进行关闭,使得使用基数减1。当子进程终结的时候,系统会在将使用基数减1,使得子进程的进程内核对象和线程内核对象的使用基数变为0,这样内核对象就可以被释放了。

CloseHandle(pi.hProcess); //关闭子进程的句柄

CloseHandle(pi.hThread); //关闭子进程中主线程的句柄

}

父进程写匿名管道:

char *buf="hello world";

DWORD dwWrite;

if(!WriteFile(hWrite,buf,strlen(buf)+1,&dwWrite,NULL))

{

MessageBox("匿名管道写入数据失败!");

return;

}

父进程读匿名管道:

char buf[100];

DWORD dwRead;

if(!ReadFile(hRead,buf,100,&dwRead,NULL))

{

MessageBox("匿名管道读取数据失败!");

return;

}

MessageBox(buf);

创建子进程程序:

可以将获取父进程的匿名管道的读写句柄操作放在CView类的OnInitialUpdate方法中实现,该方法是在CView完全构造后调用的第一个方法。代码如下:

hRead=GetStdHandle(STD_INPUT_HANDLE);

hWrite=GetStdHandle(STD_OUTPUT_HANDLE);

子进程的读写匿名管道的代码和父进程的一样,这里不再累述。

为了让子进程从众多继承的句柄中区分出管道的读、写句柄,就必须将子进程的特殊句柄设置为管道的读写句柄。

参考

[1]MSDN

[2]《VC++ 深入》

[3]http://blog.csdn.net/liufei_learning/archive/2009/12/17/5026410.aspx

8、进程通信-匿名管道相关推荐

  1. Linux进程通信——匿名管道、命名管道、管道的特性和共享内存

    Linux进程通信--匿名管道.命名管道.管道的特性和共享内存 一.管道 1.1 什么是管道? 1.2 匿名管道 <1> 匿名管道参数说明 <2> fork共享管道原理 < ...

  2. 2.12父子进程通过匿名管道通信

    目录 1.pipe函数 2.查看管道缓冲大小 1.pipe函数 #include <unistd.h> int pipe(int pipefd[2]);功能:创建一个匿名管道,用来进程间通 ...

  3. Linux编程:多个子进程与父进程使用匿名管道读写

    编写程序,在程序中父进程先后创建子进程1和子进程2.父子三个进程并发执行,并利用同一个匿名管道通信:两个子进程分别向管道写一则信息(内容自定,但要求包含子进程信息):父进程从管道读出信息并显示出来(要 ...

  4. 【Linux系统编程】进程通信之管道

    1.进程间通信介绍 1.1 进程通信的基本概念 在之前我们已经学习过进程地址空间.Linux 环境下,进程地址空间相互独立,每个进程各自有不同的用户地址空间.任何一个进程的全局变量在另一个进程中都看不 ...

  5. 进程通信——命名管道

    目录 1.Creat 2.Open 3.Read/Write 4.Wait 5.Close 6.Delete 管道是 SylixOS 进程间通信的一种方式. 管道分为匿名管道 pipe 和命名管道 f ...

  6. php管道邮件,php进程通信-PIPE管道通信

    上一篇文章讲到了php进程通信的进程信号通信方法,本文介绍的是有名管道: 管道通信,主要是利用文件,写入以及读取来进行通信的, 通俗来讲,就是A进程在1.txt写入1,B进程读取1.txt,就能读取到 ...

  7. Linux进程通信之管道

    进程间完成数据传递需要借助操作系统提供的特殊的方法,比如:文件.管道.信号.共享内存.消息队列.套接字.命名管道等.但现在常用的进程间通信方式有: 管道 – 使用最简单 pipe 管道一般读写行为 F ...

  8. 6.进程通信 无名管道 有名管道

    进程间通信(IPC,InterProcess Communication) 概念:就是进程和进程之间交换信息. 常用通信方式 无名管道(pipe) 有名管道 (fifo) 信号(signal) 共享内 ...

  9. linux通信管道破裂,Linux下进程通信之管道

    每个进程各自有不同的用户地址空间,任何一个进程的全局变量在另一个进程中都看不到,所以进程之间要交换数据必须通过内核,在内核中开辟一块缓冲区,进程1把数据从用户空间拷到内核缓冲区,进程2再从内核缓冲区把 ...

  10. 进程通信:管道(pipe)和socketpair区别

    管道pipe是半双工的,pipe两次才能实现全双工,使得代码复杂.socketpair直接就可以实现全双工 socketpair对两个文件描述符中的任何一个都可读和可写,而pipe是一个读,一个写 详 ...

最新文章

  1. Hibernate学习(九)———— 二级缓存和事务级别详讲
  2. STL queue priority_queue
  3. 一文了解可视化的主成分分析(附教程)
  4. deeplearning URL
  5. redis 附近的人_Redis GEO地理位置信息,查看附近的人
  6. Bash脚本教程之行操作
  7. 【C++】rand函数的基本使用
  8. 前端学习(1898)vue之电商管理系统电商系统之渲染用户的对话框
  9. echarts mysql_ECharts实现mysql 数据图表化
  10. 八年级信息技术认识计算机网络,初二信息技术课名称:认识计算机网络.doc
  11. es 时间字段聚合_ES聚合命令
  12. [2019上海网络赛F题]Rhyme scheme
  13. windowForm资料
  14. Windows 实时语音转文字|免费语音视频翻译转文字|语音会议记录方案
  15. 栈的链式表示+判断表达式括号是否配对
  16. Nginx实现高可用
  17. win8计算机可用内存不足,win8电脑运行提示物理内存不足的解决方法
  18. 浏览器拍照功能(Vue+ElementUI组件)
  19. Kafka之消费全流程
  20. C++新特性——郭炜

热门文章

  1. 用C#实现在PowerPoint文档中搜索文本
  2. libev源码解析——调度策略
  3. Caffe源码中io文件分析
  4. 【C++】Google C++编码规范(四):其他C++
  5. python逐个读取文件并处理_逐个读取多个文件并用python进行处理
  6. 单链表逆序生成及逆置的完整实现
  7. 使用git命令上传本地文件到GitHub上
  8. LinkQueue的基本创建
  9. 访问系统相册或调用摄像头
  10. Vue mixins(混入) 附代码示例详解