CreatePipe/CreateProcess[通俗易懂]

CreatePipe/CreateProcess[通俗易懂]管道(Pipe)实际是用于进程间通信的一段共享内存,创建管道的进程称为管道服务器,连接到一个管道的进程为管道客户机。一个进程在向管道写入数据后,另一进程就可以从管道的另一端将其读取出来。匿名管道(AnonymousPipes)是在父进程和子进程间单向传输数据的一种未命名的管道,只能在本地计算机中使用,而不可用于网络间的通信。      匿名管道实施细则      匿名管道由Cre

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

管道(Pipe)实际是用于进程间通信的一段共享内存,创建管道的进程称为管道服务器,连接到一个管道的进程为管道客户机。一个进程在向管道写入数据后,另一进程就可以从管道的另一端将其读取出来。匿名管道(Anonymous Pipes)是在父进程和子进程间单向传输数据的一种未命名的管道,只能在本地计算机中使用,而不可用于网络间的通信。
  
    匿名管道实施细则
  
    匿名管道由CreatePipe()函数创建,该函数在创建匿名管道的同时返回两个句柄:管道读句柄和管道写句柄。CreatePipe()的函数原型为:
  
  BOOL CreatePipe(PHANDLE hReadPipe, // 指向读句柄的指针
   PHANDLE hWritePipe, // 指向写句柄的指针
   LPSECURITY_ATTRIBUTES lpPipeAttributes, // 指向安全属性的指针
   DWORD nSize // 管道大小
  );
  
    通过hReadPipe和hWritePipe所指向的句柄可分别以只读、只写的方式去访问管道。在使用匿名管道通信时,服务器进程必须将其中的一个句柄传送给客户机进程。句柄的传递多通过继承来完成,服务器进程也允许这些句柄为子进程所继承。除此之外,进程也可以通过诸如DDE或共享内存等形式的进程间通信将句柄发送给与其不相关联的进程。
  
    在调用CreatePipe()函数时,如果管道服务器将lpPipeAttributes 指向的SECURITY_ATTRIBUTES数据结构的数据成员bInheritHandle设置为TRUE,那么CreatePipe()创建的管道读、写句柄将会被继承。管道服务器可调用DuplicateHandle()函数改变管道句柄的继承。管道服务器可以为一个可继承的管道句柄创建一个不可继承的副本或是为一个不可继承的管道句柄创建一个可继承的副本。CreateProcess()函数还可以使管道服务器有能力决定子进程对其可继承句柄是全部继承还是不继承。
  
    在生成子进程之前,父进程首先调用Win32 API SetStdHandle()使子进程、父进程可共用标准输入、标准输出和标准错误句柄。当父进程向子进程发送数据时,用SetStdHandle()将管道的读句柄赋予标准输入句柄;在从子进程接收数据时,则用SetStdHandle()将管道的写句柄赋予标准输出(或标准错误)句柄。然后,父进程可以调用进程创建函数CreateProcess()生成子进程。如果父进程要发送数据到子进程,父进程可调用WriteFile()将数据写入到管道(传递管道写句柄给函数),子进程则调用GetStdHandle()取得管道的读句柄,将该句柄传入ReadFile()后从管道读取数据。
  
    如果是父进程从子进程读取数据,那么由子进程调用GetStdHandle()取得管道的写入句柄,并调用WriteFile()将数据写入到管道。然后,父进程调用ReadFile()从管道读取出数据(传递管道读句柄给函数)。
  
    在用WriteFile()函数向管道写入数据时,只有在向管道写完指定字节的数据后或是在有错误发生时函数才会返回。如管道缓冲已满而数据还没有写完,WriteFile()将要等到另一进程对管道中数据读取以释放出更多可用空间后才能够返回。管道服务器在调用CreatePipe()创建管道时以参数nSize对管道的缓冲大小作了设定。
  
    匿名管道并不支持异步读、写操作,这也就意味着不能在匿名管道中使用ReadFileEx()和WriteFileEx(),而且ReadFile()和WriteFile()中的lpOverLapped参数也将被忽略。匿名管道将在读、写句柄都被关闭后退出,也可以在进程中调用CloseHandle()函数来关闭此句柄
  
  
  
  /
  匿名管道程序示例
  
    总的来说,匿名管道程序是比较简单的。在下面将要给出的程序示例中,将由父进程(管道服务器)创建一个子进程(管道客户机),子进程回见个其全部的标准输出发送到匿名管道中,父进程再从管道读取数据,一直到子进程关闭管道的写句柄。其中,匿名管道服务器程序的实现清单如下:
  
  STARTUPINFO si;
  PROCESS_INFORMATION pi;
  char ReadBuf[100];
  DWORD ReadNum;
  HANDLE hRead; // 管道读句柄
  HANDLE hWrite; // 管道写句柄
  BOOL bRet = CreatePipe(&hRead, &hWrite, NULL, 0); // 创建匿名管道
  if (bRet == TRUE)
   printf(“成功创建匿名管道!\n”);
  else
   printf(“创建匿名管道失败,错误代码:%d\n”, GetLastError());
   // 得到本进程的当前标准输出
   HANDLE hTemp = GetStdHandle(STD_OUTPUT_HANDLE);
   // 设置标准输出到匿名管道
   SetStdHandle(STD_OUTPUT_HANDLE, hWrite);
   GetStartupInfo(&si); // 获取本进程的STARTUPINFO结构信息

           TCHAR szCommandLine[] = TEXT(“Client.exe”);

           bRet = CreateProcess(NULL, szCommandLine, NULL, NULL, TRUE, NULL, NULL, NULL, &si, &pi); // 创建子进程
   SetStdHandle(STD_OUTPUT_HANDLE, hTemp); // 恢复本进程的标准输出
   if (bRet == TRUE) // 输入信息
    printf(“成功创建子进程!\n”);
   else
    printf(“创建子进程失败,错误代码:%d\n”, GetLastError());
    CloseHandle(hWrite); // 关闭写句柄
    // 读管道直至管道关闭
    while (ReadFile(hRead, ReadBuf, 100, &ReadNum, NULL))

              // 有注意到:当Client.ext进程中的数据输出到管道但没有回车,这里ReadFile仍然等待,不知道什么原因???
    {

     ReadBuf[ReadNum] = ‘\0’;
     printf(“从管道[%s]读取%d字节数据\n”, ReadBuf, ReadNum);
    }
    if (GetLastError() == ERROR_BROKEN_PIPE) // 输出信息
     printf(“管道被子进程关闭\n”);
    else
     printf(“读数据错误,错误代码:%d\n”, GetLastError());
  
    在本示例中,将当前进程的标准输出设置为使用匿名管道,再创建子进程,子进程将继承父进程的标准输出,然后再将父进程的标准输出恢复为其初始状态。于是父进程便可从管道读取数据,直到有错误发生或关闭管道写入端的所有句柄。创建的子进程只是向标准输出和标准错误发送一些文本信息,其中发送给标准输出的文本将重定向输出到管道,发送给标准错误的文本将不改变输出。下面给出子进程的实现代码:
  
  int main(int argc, char* argv[])
  {

   for (int i = 0; i < 100; i++) // 发送一些数据到标准输出和标准错误
   {

    printf(“i = %d\n”, i); // 打印提示
    cout << “标准输出:”  << i << endl; // 打印到标准输出

              // 按照下面的的格式输出,上面的ReadFile一直处于等待状态

              // cout << “标准输出:”  << i;
    cerr  <<  “标准错误:” <<  i << endl; // 打印到标准错误
   }
   return 0;
  }

原文:http://blog.tianya.cn/blogger/post_read.asp?BlogID=1509063&PostID=17562664

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/159384.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • java 零拷贝_java深拷贝

    java 零拷贝_java深拷贝在传统的数据IO模式中,读取一个磁盘文件,并发送到远程端的服务,就共有四次用户空间与内核空间的上下文切换,四次数据复制,分别是两次CPU数据复制,两次DMA数据复制。零拷贝指在进行数据IO或传输时,数据在用户态下经历了零次拷贝,并非不拷贝数据。通过减少数据传输过程中内核缓冲区和用户进程缓冲区间不必要的CPU数据拷贝与用户态和内核态的上下文切换次数,降低CPU在这两方面的开销,释放CPU执行其他任务,更有效的利用系统资源,提高传输效率,同时还减少了内存的占用,提升应用程序的性能

    2022年9月21日
    0
  • 一键锁定计算机快捷方式,还原win8系统创建一键锁定计算机的快捷方式的技巧…

    一键锁定计算机快捷方式,还原win8系统创建一键锁定计算机的快捷方式的技巧…今天和大家分享一下关于对win8系统创建一键锁定计算机的快捷方式设置的方法,在使用win8系统的过程中经常不知道如何去对win8系统创建一键锁定计算机的快捷方式进行设置,有什么好的办法去设置win8系统创建一键锁定计算机的快捷方式呢?在这里小编教你只需要1、首先在桌面上的空白处鼠标右击选择“新建–快捷方式”,然后在弹出来的创建快捷方式界面中,在“请键入对象的位置”框中输入:rundll32.ex…

    2022年7月21日
    14
  • ExcelReport.cs Excel操作类、实例源码下载

    ExcelReport.cs Excel操作类、实例源码下载

    2021年11月17日
    35
  • windows下php7.1安装redis扩展以及redis测试使用全过程

    windows下php7.1安装redis扩展以及redis测试使用全过程

    2021年10月21日
    54
  • 《大话数据结构》目录[通俗易懂]

    《大话数据结构》目录[通俗易懂]由于目录中有比较复杂的格式,所以只能用PDF的形式提供。http://files.cnblogs.com/cj723/%E7%9B%AE%E5%BD%95.pdf

    2022年6月24日
    32
  • Charle工具详解之实战演练问题分析、https抓包、流量设置、断点配置

    Charle工具详解之实战演练问题分析、https抓包、流量设置、断点配置目录一 问题分析二 https 的抓包 windows 证书的配置 CharlesHttps 代理的配置 MacOS 证书的配置 IOS 证书配置三 Charles 流量设置断点配置主要包含 问题分析 https 抓包弱网测试断点调试一 问题分析分析出前端问题还是后台问题问题描述 测试地址 http ihrm test itheima net login 实施步骤二 https 的抓包 https 不设置证书的时候抓的报文是乱码

    2025年6月9日
    1

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号