同一台服務期間父子程序間通信可以使用管道的方式進行通信。管道分為匿名管道和命名管道兩種,匿名管道主要用于兩個程序間有父子關系的程序間通信,命名管道主要用于沒有父子關系的程序間通信。
今天先簡單的說下匿名管道的應用。
以下代碼為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
然後運作父程序即可通過在父程序循環輸入内容,而子程序循環讀取父程序輸入的内容