您的位置:首页 > 其它

进程间通信---匿名管道pipe

2014-01-28 13:04 567 查看
同一台服务期间父子进程间通信可以使用管道的方式进行通信。管道分为匿名管道和命名管道两种,匿名管道主要用于两个进程间有父子关系的进程间通信,命名管道主要用于没有父子关系的进程间通信。

今天先简单的说下匿名管道的应用。

以下代码为parent.cpp文件的代码

/* purpose @ 验证管道的基本应用,通过基本的协议规则,先写入大小再写入数据达到通信目的
* date    @ 2014.01.24
* author  @ haibin.wang
*/

#include<unistd.h>
#include<stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <errno.h>
#include <iostream>
#include <string>

#define MASTER_WRITE 11

int main(int argc, char** argv)
{
int fildes[2];
pid_t pid;
int i,j;
char buf[256];
if(pipe(fildes)<0)
{
fprintf(stderr,"pipe error!\n");
return 1;
}
if((pid = fork())<0)
{
fprintf(stderr,"fork error!\n");
return 1;
}
if(pid == 0)
{
close(fildes[1]); //子进程关闭写

argv[0] = "child"; //修改子程序的名字,会报warning

if(-1 == dup2(fildes[0],MASTER_WRITE)) //复制读句柄为固定数字MASTER_WRITE
{
printf("dup2 error%s\n", strerror(errno));
}
if(-1 ==close(fildes[0])) //关闭老的句柄
{
printf("child colse(fildes[0]) failed:%s\n", strerror(errno));
}
execvp("/home/test/pipetest/child1", argv); //指定子程序的路径
close(fildes[MASTER_WRITE]);
return 1;
}

if(-1 == close(fildes[0]))
{
printf("parent colse(fildes[0]) failed:%s\n", strerror(errno));
}
while(1)
{
std::string str;
getline(std::cin,str); //获取用户输入
if(str.compare("exit") == 0)
{
int iOut = -1;
write(fildes[1],&iOut, sizeof(int)); //写入数据大小
break;
}
int length = str.length();
write(fildes[1],&length, sizeof(int)); //写入数据大小
write(fildes[1],str.c_str(), str.length()); //写书真实数据
}
waitpid(pid,NULL,0);
printf("parent to exit!\n");
close(fildes[1]);
return 0;
}


以下代码为child.cpp文件的代码

/* purpose @ 子进程接收父进程传递参数,然后等待父进程写入数据,阻塞在读上
*          验证管道数据传输,在父进程中通过dup2将打开的句柄设置为MASTER_WRITE,子进程可以直接进行读取
*           当子进程读取到数据长度为-1的时候退出
* date    @ 2014.01.27
* author  @ haibin.wang
*/

#include <unistd.h>

#include <stdio.h>
#include <string.h>

#define MASTER_WRITE 11

int main(int argc, char** argv)
{
for(int i=0; i<argc; ++i)
{
printf("argv[%d]=%s\n",i,argv[i]);
}

char buf[255];
while(1)
{
memset(buf,0,sizeof(buf));
int length = 0;
read(MASTER_WRITE, &length, sizeof(int)); //子进程先读取长度,再读取数据内容
if(-1 == length)
{
printf("child exist\n");
break;
}
else if( length >0)
{
read(MASTER_WRITE, buf, length);
printf("cur=%d,,,,data = %s,,,\n",length, buf);
}
}
}


执行以下编译命令生成父子程序,

g++ parent.cpp -o parent

g++ child.cpp -o child

然后运行父进程即可通过在父进程循环输入内容,而子进程循环读取父进程输入的内容
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: