雑なメモ書き

気楽にいきます

pipe経由でreadは読み出し可能になるまで停止する

linuxjm.osdn.jp

読んでいたら、blockしてくれるぽいこと書いてあったので確認

プロセスが空のパイプから読み出しを行おうとした場合、 read(2) はデータが読み出し可能になるまで停止する。

#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#include <sys/types.h>
#include <sys/wait.h>


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

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

    switch(childPid = fork()) {
        case -1:
            exit(EXIT_FAILURE);
        case 0:
            printf("pid: %d\n",getpid());
            close(pipefd[1]);

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

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

            break;
        default:
            printf("pid: %d\n",getpid());

            close(pipefd[0]);

            wait(NULL);
    }
    return 0;
}

ただし、closeするとend-of-fileになって進んでしまう。

close(pipefd[1]);

確認

  • read systemcallで止まっていることが確認出来る
 strace -ff ./process-pipe
execve("./process-pipe", ["./process-pipe"], 0x7ffd75ee4908 /* 13 vars */) = 0
brk(NULL)                               = 0x5638565c0000
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
access("/etc/ld.so.preload", R_OK)      = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=15442, ...}) = 0
mmap(NULL, 15442, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7fbdc90ce000
close(3)                                = 0
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\260\34\2\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0755, st_size=2030544, ...}) = 0
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fbdc90cc000
mmap(NULL, 4131552, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7fbdc8aba000
mprotect(0x7fbdc8ca1000, 2097152, PROT_NONE) = 0
mmap(0x7fbdc8ea1000, 24576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1e7000) = 0x7fbdc8ea1000
mmap(0x7fbdc8ea7000, 15072, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7fbdc8ea7000
close(3)                                = 0
arch_prctl(ARCH_SET_FS, 0x7fbdc90cd4c0) = 0
mprotect(0x7fbdc8ea1000, 16384, PROT_READ) = 0
mprotect(0x563854f59000, 4096, PROT_READ) = 0
mprotect(0x7fbdc90d2000, 4096, PROT_READ) = 0
munmap(0x7fbdc90ce000, 15442)           = 0
pipe([3, 4])                            = 0
clone(child_stack=NULL, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7fbdc90cd790) = 245
getpid()                                = 244
fstat(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 0), ...}) = 0
brk(NULL)                               = 0x5638565c0000
brk(0x5638565e1000)                     = 0x5638565e1000
write(1, "pid: 244\n", 9pid: 244
)               = 9
close(3)                                = 0
wait4(-1, strace: Process 245 attached
 <unfinished ...>
[pid   245] getpid()                    = 245
[pid   245] fstat(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 0), ...}) = 0
[pid   245] brk(NULL)                   = 0x5638565c0000
[pid   245] brk(0x5638565e1000)         = 0x5638565e1000
[pid   245] write(1, "pid: 245\n", 9pid: 245
)   = 9
[pid   245] close(4)                    = 0
[pid   245] read(3,

wiki.bit-hive.com

blog.livedoor.jp