700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > Unix网络编程--进程间通信--管道通信

Unix网络编程--进程间通信--管道通信

时间:2024-06-26 10:23:58

相关推荐

Unix网络编程--进程间通信--管道通信

所有式样的Unix都提供管道,它由 pipe 函数创建,提供一个单路(单向)数据流。

原型如下:

#include <unistd.h>int pipe(int fd[2]);

该函数返回两个文件描述符:fd[0] fd[1]。前者打开用于读,后者打开来写。(都是站在进程的角度上来看读和写)

管道的典型用途是以下述方式为两个不同的进程(一个是父进程,一个是子进程)提供进程间的通信手段。首先,由一个进程创建管道后调用 fork 派生出一个自身的副本,过程如下所示:

注意:其实上面这张图说明的道理没有问题,但是图的画法确实是存在问题的。因为管道是单向传输数据流的,所以,当有两个不同的进程进行通信时,需要的是两个管道协同合作,而不是上图的画法。我们可以考虑一种情况,当父进程或者是子进程往管道里写入数据,因为管道里只要有数据就可以读出,所以,如果这时如果父进程或者是子进程读管道中的数据,那么读出的可能就是刚刚写入的数据,这样,就没能完成通信的任务。

所以,如果要实现通信,正确的步骤是:

(1)创建管道1( fd1[0] 和 fd1[1] )和管道( fd2[0] 和 fd2[1] )

(2)fork;

(3)父进程关闭管道1的读出端

(4)父进程关闭管道2的写入端

(5)子进程关闭管道1的写入端

(6)子进程关闭管道2的读出端

完成了以上步骤就好像下面这张图这样:

例子:

现在描述一个客户端-服务器的例子。main 函数创建两个管道并用 fork 生成一个子进程。客户然后作为父进程运行,服务器则作为子进程运行。第一个管道用于从客户向服务器发送路径名,第二个管道用于从服务器向客户发送该文件的内容(或者是一个出错消息),这样设置完毕后就得到下图所示的情形:

下面请看实现的实例程序:

mainpipe.c

#include<sys/types.h>/* basic system data types */#include<sys/time.h>/* timeval{} for select() */#include<time.h>/* timespec{} for pselect() */#include<errno.h>#include<fcntl.h>/* for nonblocking */#include<limits.h>/* PIPE_BUF */#include<signal.h>#include<stdio.h>#include<stdlib.h>#include<string.h>#include<sys/stat.h>/* for S_xxx file mode constants */#include<unistd.h>#include<sys/wait.h>#define MAXLINE 1024void client(int, int);void server(int, int);int main(int argc, char **argv){int pipe1[2], pipe2[2];pid_t childpid;pipe(pipe1);pipe(pipe2);if ((childpid = fork()) == 0) {close(pipe1[1]);close(pipe2[0]);server(pipe1[0], pipe2[1]);exit(0);}close(pipe1[0]);close(pipe2[1]);client(pipe2[0], pipe1[1]);waitpid(childpid, NULL, 0);exit(0);}void client(int readfd, int writefd){size_t len;ssize_t n;char buff[MAXLINE];fgets(buff, MAXLINE, stdin);len = strlen(buff);if (buff[len - 1] == '\n')len--;write(writefd, buff, len);while ((n = read(readfd, buff, MAXLINE)) > 0)write(STDOUT_FILENO, buff, n);}void server(int readfd, int writefd){int fd;ssize_t n;char buff[MAXLINE+1];if ( (n = read(readfd, buff, MAXLINE)) == 0) {printf("end-of-file while reading pathname");exit(-1);}buff[n] = '\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, MAXLINE)) > 0)write(writefd, buff, n);close(fd);}}

我在主目录下放置文件 test.txt,文件内容如下所示:

Hello! This is DLUTBruceZhang!I love three things!The sun, for the day;The moon, for the night;The you, forever.

编译运行程序得到如下输出:

由此可见,利用管道实现了进程间通信。

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