| 在父进程中的 else子句将会关闭管道的读端: close(pipeFDs[ReadEnd]); /* called in parent code */
 然后父进程将向无名管道中写入某些字节数据(ASCII 代码),子进程读取这些数据,然后向标准输出中回放它们。 在这个程序中还需要澄清的一点是在父进程代码中的 wait函数。一旦被创建后,子进程很大程度上独立于它的父进程,正如简短的pipeUN程序所展示的那样。子进程可以执行任意的代码,而它们可能与父进程完全没有关系。但是,假如当子进程终止时,系统将会通过一个信号来通知父进程。 要是父进程在子进程之前终止又该如何呢?在这种情形下,除非采取了预防措施,子进程将会变成在进程表中的一个僵尸进程。预防措施有两大类型:第一种是让父进程去通知系统,告诉系统它对子进程的终止没有任何兴趣: signal(SIGCHLD, SIG_IGN); /* in parent: ignore notification */
 第二种方法是在子进程终止时,让父进程执行一个 wait。这样就确保了父进程可以独立于子进程而存在。在pipeUN程序中使用了第二种方法,其中父进程的代码使用的是下面的调用: wait(NULL); /* called in parent */
 这个对 wait的调用意味着一直等待直到任意一个子进程的终止发生,因此在pipeUN程序中,只有一个子进程。(其中的NULL参数可以被替换为一个保存有子程序退出状态的整数变量的地址。)对于更细粒度的控制,还可以使用更灵活的waitpid函数,例如特别指定多个子进程中的某一个。 pipeUN将会采取另一个预防措施。当父进程结束了等待,父进程将会调用常规的exit函数去退出。对应的,子进程将会调用_exit变种来退出,这类变种将快速跟踪终止相关的通知。在效果上,子进程会告诉系统立刻去通知父进程它的这个子进程已经终止了。
 假如两个进程向相同的无名管道中写入内容,字节数据会交错吗?例如,假如进程 P1 向管道写入内容: foo bar
 同时进程 P2 并发地写入: baz baz
 到相同的管道,最后的结果似乎是管道中的内容将会是任意错乱的,例如像这样: baz foo baz bar
 只要没有写入超过 PIPE_BUF字节,POSIX 标准就能确保写入不会交错。在 Linux 系统中,PIPE_BUF的大小是 4096 字节。对于管道我更喜欢只有一个写入方和一个读取方,从而绕过这个问题。 命名管道无名管道没有备份文件:系统将维持一个内存缓存来将字节数据从写方传给读方。一旦写方和读方终止,这个缓存将会被回收,进而无名管道消失。相反的,命名管道有备份文件和一个不同的 API。 下面让我们通过另一个命令行示例来了解命名管道的要点。下面是具体的步骤: 
    开启两个终端。这两个终端的工作目录应该相同。
    在其中一个终端中,键入下面的两个命令(命令行提示符仍然是 %,我的注释以##打头。): % mkfifo tester ## 创建一个备份文件,名为 tester% cat tester    ## 将管道的内容输出到 stdout 
 在最开始,没有任何东西会出现在终端中,因为到现在为止没有在命名管道中写入任何东西。
    在第二个终端中输入下面的命令: % cat > tester ## redirect keyboard input to the pipehello, world!  ## then hit Return keybye, bye       ## ditto<Control-C>    ## terminate session with a Control-C
 无论在这个终端中输入什么,它都会在另一个终端中显示出来。一旦键入 Ctrl+C,就会回到正常的命令行提示符,因为管道已经被关闭了。
    通过移除实现命名管道的文件来进行清理: % unlink tester
 正如 mkfifo程序的名字所暗示的那样,命名管道也被叫做 FIFO,因为第一个进入的字节,就会第一个出,其他的类似。有一个名为mkfifo的库函数,用它可以在程序中创建一个命名管道,它将在下一个示例中被用到,该示例由两个进程组成:一个向命名管道写入,而另一个从该管道读取。 示例 2. fifoWriter 程序#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h> #include <unistd.h>#include <time.h>#include <stdlib.h>#include <stdio.h> #define MaxLoops         12000   /* outer loop */#define ChunkSize           16   /* how many written at a time */#define IntsPerChunk         4   /* four 4-byte ints per chunk */#define MaxZs              250   /* max microseconds to sleep */ int main() {  const char* pipeName = "./fifoChannel";  mkfifo(pipeName, 0666);                      /* read/write for user/group/others */  int fd = open(pipeName, O_CREAT | O_WRONLY); /* open as write-only */  if (fd < 0) return -1;                       /** error **/    int i;  for (i = 0; i < MaxLoops; i++) {          /* write MaxWrites times */    int j;    for (j = 0; j < ChunkSize; j++) {       /* each time, write ChunkSize bytes */      int k;      int chunk[IntsPerChunk];      for (k = 0; k < IntsPerChunk; k++)     chunk[k] = [rand][9]();                   write(fd, chunk, sizeof(chunk));     }    usleep(([rand][9]() % MaxZs) + 1);           /* pause a bit for realism */  }   close(fd);                                /* close pipe: generates an end-of-file */  unlink(pipeName);                         /* unlink from the implementing file */  [printf][10]("%i ints sent to the pipe.n", MaxLoops * ChunkSize * IntsPerChunk);   return 0;}
 上面的 fifoWriter程序可以被总结为如下: |