您的位置:首页 > 运维架构 > Linux

《进程间通信》---------------->管道

2016-09-11 13:36 381 查看

pipe函数

#include <unistd.h>

int  pipe(int fd[2]);
fd[0]:以读的方式打开管道描述符。该函数返回两个文件描述符:fd[0]和fd[1]。

fd[1]:以写的方式打开管道描述符。

对于单进程管道的模型如图所示:

进程通过文件描述符fd[1],将数据写入管道中,通过文件描述否fd[0]读取管道中的数据。



实际中这种单进程管道很少用到,对于管道最经典的用法是为两个不同的进程提供进程间通信。其原理是父进程创建一个管道然后调用fork派生一个自身的副本(也就是所谓的子进程)。其模型如图所示:



这时候我们在父进程中关闭管道的读,在子进程中关闭管道的写,从而实现了在父子进程中的单向数据流如图所示。



对于上述管道模型,通过以下代码实现,代码中父进程先创建一个管道,然后父进程向管道中写入Helloworld,子进程读取管道中的数据。

#include<stdio.h>
#include<unistd.h>
#include<fcntl.h>
#include<stdlib.h>
#define MAXSIZE  1024
int main(int argc,char **argv)
{
int fd[2];
char write_buff[MAXSIZE]="Hello world";
char read_buff[MAXSIZE];
pid_t childpid;
pipe(fd);
//create fork
childpid = fork();
if(0 == childpid)
{
close(fd[1]); //close write
read(fd[0],read_buff,MAXSIZE);
printf("read data from pipe is %s\n",read_buff);
exit(0);
}
close(fd[0]);
write(fd[1],write_buff,MAXSIZE);
waitpid(childpid,NULL,0);
exit(0);
}


接下来我们通过管道实现客户——服务器例子。Main函数创建两个管道并用fork生成一个子进程。客户然后作为父进程运行,服务器作为子进程运行。第一个管道用于从客户向服务器发送路径名,第二个管道用于从服务器向客户发送该文件的内容。

 


 
 

#include<stdlib.h>
#include<unistd.h>
#include<stdio.h>
#include<fcntl.h>
#include<errno.h>
#include<string.h>
#define MAXSIZE 1024
void server_write_client_read(int readfd,int writefd);
void client_write_server_read(int readfd,int writefd);
int main(int argc,char **argv)
{
//two pipe
int clientToServer[2];
int serverToClient[2];
pipe(clientToServer);
pipe(serverToClient);
//create fork
pid_t childpid;
childpid = fork();
if(childpid == 0)
{
close(clientToServer[1]);
close(serverToClient[0]);
server_write_client_read(clientToServer[0],serverToClient[1]);
exit(0);
}
close(clientToServer[0]);
close(serverToClient[1]);
client_write_server_read(serverToClient[0],clientToServer[1]);
waitpid(childpid,NULL,0);
exit(0);
}
void client_write_server_read(int readfd,int writefd)
{
size_t len;
int n;
char buff[MAXSIZE];
fgets(buff,MAXSIZE,stdin);
len = strlen(buff);
if(buff[len - 1] == '\n')
len--;
write(writefd,buff,len);
while((n = read(readfd,buff,MAXSIZE)) > 0)
write(STDOUT_FILENO,buff,n);
}
void server_write_client_read(int readfd,int writefd)
{
int fd;
int n;
char buff[MAXSIZE + 1];
if((n = read(readfd,buff,MAXSIZE)) == 0)
printf("read file path error\n");
buff
= '\0';
if((fd = open(buff,O_RDONLY)) < 0)
{
snprintf(buff+n,sizeof(buff)-n,":can't open, %s\n",strerror(errno));
n = strlen(buff);
write(writefd,buff,n);
}
else
{
while((n = read(fd,buff,MAXSIZE)) > 0)
write(writefd,buff,n);
close(fd);
}
}


更多Linux信息关注小牛驿站微信公众号

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息