読書ノート:第4章パイプとFIFO(2)
2017 ワード
『UNIXネットワークプログラミング:ボリューム2』P 38図4-14全二重配管の双方向通信能力をテストする
ここの全二重パイプは2つの半二重パイプで構成されています.fd[1]に書き込まれたデータはfd[0]からのみ読み出され、fd[0]に書き込まれたデータはfd[1]からのみ読み出される.
フルデュプレクスパイプを作成しforkを呼び出し、親プロセスは文字pを書き込み、そこから文字を読み出します.サブプロセスは、まず3秒間睡眠し、このパイプから1文字を読み出した後、文字cに書き込む.サブプロセススリープは、親プロセスのread呼び出しがサブプロセスのreadより先に実行されるようにして、親プロセスが自分の書いた文字を読み返すかどうかを見るためです.
Ubuntu 14.04で実行:
親プロセスは、サブプロセスによって読み出される文字pを書き込むが、その後、親プロセスはfd[1]readから中止しようとすると中止し、サブプロセスはfd[0]writeへ中止しようとすると中止する.
これにより、Linuxはデフォルトで半二重パイプラインを提供しています(コンパイル時に異なるオプションを指定し、全二重パイプラインを提供できますか?)
/*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はデフォルトで半二重パイプラインを提供しています(コンパイル時に異なるオプションを指定し、全二重パイプラインを提供できますか?)