読書ノート:第4章パイプとFIFO(2)


『UNIXネットワークプログラミング:ボリューム2』P 38図4-14全二重配管の双方向通信能力をテストする
/*P38 fduplex.c */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>

int main(int argc, char *argv[])
{
	int		fd[2], n;
	char	c;
	pid_t	childpid;

	//  
	if (pipe(fd) < 0) {
		fprintf(stderr, "pipe error: %s
", strerror(errno)); exit(1); } //  if ((childpid = fork()) < 0) { fprintf(stderr, "fork error: %s
", strerror(errno)); exit(1); } else if (childpid == 0) { //  sleep(3); //  0 if ((n = read(fd[0], &c, 1)) != 1) { if (n < 0) fprintf(stderr, "read error: %s
", strerror(errno)); fprintf(stderr, "child: read returned %d
", n); exit(1); } printf("child read %c
", c); //  0 if (write(fd[0], "c", 1) != 1) { fprintf(stderr, "write error: %s
", strerror(errno)); exit(1); } exit(0); } //  //  1 if (write(fd[1], "p", 1) != 1){ fprintf(stderr, "write error:%s
", strerror(errno)); exit(1); } //  1 if ((n = read(fd[1], &c, 1)) != 1) { fprintf(stderr, "read error: %s
", strerror(errno)); fprintf(stderr, "parent: read returned %d
", n); exit(1); } printf("parent read %c
", c); exit(0); }

ここの全二重パイプは2つの半二重パイプで構成されています.fd[1]に書き込まれたデータはfd[0]からのみ読み出され、fd[0]に書き込まれたデータはfd[1]からのみ読み出される.
フルデュプレクスパイプを作成しforkを呼び出し、親プロセスは文字pを書き込み、そこから文字を読み出します.サブプロセスは、まず3秒間睡眠し、このパイプから1文字を読み出した後、文字cに書き込む.サブプロセススリープは、親プロセスのread呼び出しがサブプロセスのreadより先に実行されるようにして、親プロセスが自分の書いた文字を読み返すかどうかを見るためです.
Ubuntu 14.04で実行:
$ ./fduplex 
read error: Bad file descriptor
parent: read returned -1
$ child read p
write error: Bad file descriptor

親プロセスは、サブプロセスによって読み出される文字pを書き込むが、その後、親プロセスはfd[1]readから中止しようとすると中止し、サブプロセスはfd[0]writeへ中止しようとすると中止する.
これにより、Linuxはデフォルトで半二重パイプラインを提供しています(コンパイル時に異なるオプションを指定し、全二重パイプラインを提供できますか?)