现在的位置: 首页 > 综合 > 正文

无名管道与有名管道

2018年04月10日 ⁄ 综合 ⁄ 共 1972字 ⁄ 字号 评论关闭

1)无名管道:

          /*linux 自带源码*/

       #include <sys/wait.h>
       #include <stdio.h>
       #include <stdlib.h>
       #include <unistd.h>
       #include <string.h>

       int main(int argc, char *argv[])
       {
           int pipefd[2];
           pid_t cpid;
           char buf;

           if (argc != 2) {
            fprintf(stderr, "Usage: %s <string>\n", argv[0]);
            exit(EXIT_FAILURE);
           }

           if (pipe(pipefd) == -1) {
               perror("pipe");
               exit(EXIT_FAILURE);

           }

           cpid = fork();
           if (cpid == -1) {
               perror("fork");
               exit(EXIT_FAILURE);
           }

           if (cpid == 0) {    /* Child reads from pipe */
               close(pipefd[1]);          /* Close unused write end */

               while (read(pipefd[0], &buf, 1) > 0)
                   write(STDOUT_FILENO, &buf, 1);

               write(STDOUT_FILENO, "\n", 1);
               close(pipefd[0]);
               _exit(EXIT_SUCCESS);

            } else {            /* Parent writes argv[1] to pipe */
               close(pipefd[0]);          /* Close unused read end */
               write(pipefd[1], argv[1], strlen(argv[1]));
               close(pipefd[1]);          /* Reader will see EOF */
               wait(NULL);                /* Wait for child */
               exit(EXIT_SUCCESS);
           }
       }

//为什么要在父进程里关闭读端  close[fd[0]]   --------在子进程里关闭写端                 close[fd[1]]

解惑:为了在父进程中创建管道,需要先定义一个包含两个元素的整型数组,用来存放管道读端和写端对应的文件描述符。

该数组在创建管道时作为参数传递。要注意的是,管道是一种半双工方式,即对于进程来说,要么只能读管道,要么只能写管道。不允许对管道又读又写

//无名管道会阻塞吗?

解惑:会的

<1>当写端存在时,管道中没有数据时,读取管道时将阻塞
<2>当读端请求读取的数据大于管道中的数据时,此时读取管道中实际大小的数据
<3>当读端请求读取的数据小于管道中的数据时,此时放回请求读取的大小数据

         特殊情况:

管道缓冲区一有空闲区域,写进程就会试图向管道写入数据。当管道满时,读进程不读走管道缓冲区中的数据,那么写操作将一直阻塞。

2)有名管道:

                         只有读端存在,写端才有意义。如果读端不在,写端向FIFO写数据,内核将向对应的进程发送SIGPIPE信号(默认终止进程)

                        比无名管道多了一个open函数

A.从FIFO中读取数据

  如果一个进程为了从FIFO中读取数据而以阻塞的方式打开FIFO, 则称内核为该进程的读操作设置了阻塞标志

  如果写端关闭,管道中有数据读取管道中的数据,如果管道中没有数据读端将不会继续阻塞,此时返回0

B.向FIFO中写入数据

   如果一个进程为了向FIFO中写入数据而阻塞打开FIFO,那么称该进程内的写操作设置了阻塞标志

  读端不在,写端向FIFO写数据,内核将向对应的进程发送SIGPIPE信号(默认终止进程)

【上篇】
【下篇】

抱歉!评论已关闭.