1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > 代码超详细讲解:C语言进程间通信之SuperMario管道pipe(无名管道)

代码超详细讲解:C语言进程间通信之SuperMario管道pipe(无名管道)

时间:2022-07-28 20:27:25

相关推荐

代码超详细讲解:C语言进程间通信之SuperMario管道pipe(无名管道)

PIPE目录

1. client与server通信2. 图解3. client和server进程通信简单代码实现lient.cserver.c

1. client与server通信

client和server进程之间如何通信举个简单例子:

client端标准输入standard input,读进一个路径到buffer中,并把路径写入管道服务器从管道中读取这个路径到buffer中进行read操作: read成功,写入管道返回给clientread失败,也要回应client错误信息 client从管道中stdout到buffer来显示内容

管道由pipe函数创建,并提供一个单向数据流,管道一般是两个不同进程间的通信,父进程和子进程(只能是亲缘关系之间),先由一个父进程创建一个管道,再调用fork函数派生

2. 图解

画个图举个例子:

上述有两个管道pipe1和pipe2,半双工单向,往一个方向的数据流,需要一来一回就是创建两个pipe,双向数据流。

这里的client为父,server是派生出来的子

int pipe(int fd[2]); //ret 0 indicates success, else ret -1

fd[0] 用做写入信息到管道

fd[1] 用做读取管道信息

步骤如下:

创建pipe1和pipe2 , pipe1 fd[0]负责读,fd[1]负责写,pipe2 fd同理fork进行派生父进程关闭从pipe1读出端fd1[0]父进程关闭从pipe2写入端fd2[1]子进程关闭从pipe1写入端fd1[1]子进程关闭从pipe2读出端fd2[0]

WARNING:两个管道连接着两个进程,client和server在进行读出和写入的过程都穿越了内核

3. client和server进程通信简单代码实现

main.c

#include <stdio.h>#include "unpipc.h"void client(int,int), server(int,int);int main(int argc, char** argv){//pipe1 includes fd1[0], fd1[1]//pipe2 includes fd2[0], fd2[1]int pipe1[2], pipe2[2];pid_t childpid;//创建两个pipepipe(pipe1);pipe(pipe2);//判断是否childif( (childpid = fork())==0 ){/*关闭子进程中的 管道1的写入,关闭管道2的读出*/close(pipe1[1]);close(pipe2[0]);//调用server function,server端 传入管道1的读出,管道2的写入server(pipe1[0], pipe2[1]);exit(0);}/*关闭父进程中的 管道1的读出, 关闭管道2的写入*/close(pipe1[0]);close(pipe2[1]);//调用client function,client端 传入管道2的读出,管道1的写入client(pipe2[0], pipe1[1]);//等待child进程waitpid(childpid, NULL, 0);exit(0);}}

client.c

void client(int readfd, int writefd){size_t len;ssize_t n;char buff[MAXLINE];//获取标准输入到bufferfgets(buff, MAXLINE, stdin);len = strlen(buff);if(buff[len-1] == '\n' ) /*去掉回车符*/len--;//将buff info写入到管道write(writefd, buff, len);//读取buffer中的信息并标准输出while( (n = read(readfd, buff, MAXLINE)) >0 ){write(STDOUT_FILENO, buff, n);}

server.c

void server(int readfd, int writefd){int fd;ssize_t n;char buff[MAXLINE+1];//从管道中读取info到bufferif( (n=read(readfd, buff, MAXLINE)) == 0)printf("end of file while reading pathname");buff[n] = '\0';//进行打开读取操作,成功则写入到buffer,否则把错误信息写入到管道if((fd = open(buff, O_RDONLY)) < 0 ){snprintf(buff+n, sizeof(buff)-n, ": cant open, %s \n", strerror(errno) );n = strlen(buff);write(writefd, buff, n);}else{while((n = read(fd, buff, MAXLINE))>0 )write(writefd, buff, n);close(fd);}}

如果对你有帮助,一键三连 All the best plus thank you~ 😃

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。