CreatePipe匿名管道通信

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


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结构信息
   bRet = CreateProcess(NULL, “Client.exe”, 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))
    {

     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; // 打印到标准输出
    cerr << “标准错误:” << i << endl; // 打印到标准错误
   }
   return 0;

  } 

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

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

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

相关推荐

  • jbpm工作流

    jbpm工作流一、JBPM(javabusinessprocessmanager)1、工作流管理流程O>定义工作流(使用流程设计器生成,png和xml文件,分别面向用户和系统)>执行工作流

    2022年7月2日
  • java 启动连接hsql

    java 启动连接hsqljava启动连接HSQL转载自: http://ehilcoder.iteye.com/blog/17228051.关于HSQLAHyperSQLDatabaseEachHyperSQLdatabaseiscalledacatalog.Therearethreetypesofcatalogdependingonhowthedataisstored.Typ

    2022年9月17日
  • JMH简介

    JMH简介  JMH是新的microbenchmark(微基准测试)框架(2013年首次发布)。与其他众多框架相比它的特色优势在于,它是由Oracle实现JIT的相同人员开发的。特别是我想提一下AlekseyShipilev和他优秀的博客文章。JMH可能与最新的OracleJRE同步,其结果可信度很高。JMH的示例链接。使用JMH仅需满足2个必要条件(其他所有都是建议选项):设置jmh-…

    2022年7月11日
  • mysql经典50道练习题

    mysql经典50道练习题问题及描述:–1.学生表Student(SID,Sname,Sage,Ssex)–SID学生编号,Sname学生姓名,Sage出生年月,Ssex学生性别–2.课程表Course(CID,Cname,TID)–CID–课程编号,Cname课程名称,TID教师编号–3.教师表Teacher(TID,Tname)–TID教师编号,Tname教师姓名–4.成绩……

    2022年9月18日
  • 推荐60多个CSS GALLERY画廊网站

    推荐60多个CSS GALLERY画廊网站

    2021年8月6日
  • vs 错误LNK2019 无法解析的外部符号 __imp__PathFileExistsA@

    vs 错误LNK2019 无法解析的外部符号 __imp__PathFileExistsA@尝试:在main函数前添加:#pragmacomment(lib,”Shlwapi.lib”)

    2022年7月14日

发表回复

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

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