簡體   English   中英

從 pipe 讀取數據時的奇怪行為

[英]Strange behavior when reading data from pipe

在仔細閱讀手冊(即man 2 pipe )后,我找到了一個演示代碼片段:

       #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);
           }
       }

我對上面的代碼片段做了一些小的修改(即:在父進程中添加sleep & 在子進程中打印出read返回的大小)。

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

int
main(int argc, char *argv[])
{
    int pipefd[2];
    pid_t cpid;
    std::array<char, 1024> buf;
    
    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 */
        int size;
        while (size = read(pipefd[0], buf.data(), 1) > 0)
             std::cout << size << std::endl;
        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 */
        std::string str{"hello world\n"};
        write(pipefd[1], str.c_str(), str.size());
        std::this_thread::sleep_for(std::chrono::seconds(5));
        close(pipefd[1]);          /* Reader will see EOF */
        wait(NULL);                /* Wait for child */
        exit(EXIT_SUCCESS);
    }
}

這是上面代碼片段的 output:

1
1
1
1
1
1
1
1
1
1
1
1

目前看來一切正常。 令人困惑的是,當我增加要讀取的字節數時。output 非常奇怪。這是上述代碼片段

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

int
main(int argc, char *argv[])
{
    int pipefd[2];
    pid_t cpid;
    std::array<char, 1024> buf;
    
    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 */
        int size;
        while (size = read(pipefd[0], buf.data(), buf.size()) > 0)
             std::cout << size << std::endl;
        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 */
        std::string str{"hello world\n"};
        write(pipefd[1], str.c_str(), str.size());
        std::this_thread::sleep_for(std::chrono::seconds(5));
        close(pipefd[1]);          /* Reader will see EOF */
        wait(NULL);                /* Wait for child */
        exit(EXIT_SUCCESS);
    }
}

這是奇怪的 output:

1
//new line, and no more output indeed.

也許我需要知道pipe返回的文件描述符使用哪種類型的緩沖。而且我找不到任何有用的手冊信息(即man 2 pipe )。

任何人都可以闡明這件事嗎?

>運算符優先級高於= 因此,

size = read(pipefd[0], buf.data(), buf.size()) > 0

相當於

size = (read(pipefd[0], buf.data(), buf.size()) > 0)

第一次迭代似乎會消耗所有數據,因此read應該返回12 12 > 0true ,並且true隱式轉換為整數值1

下一次迭代, read應該返回一個非正數,結束循環。

read大小為1時,其預期返回值與1 > 0的結果無法區分。

將括號放在作業周圍。

(size = read(pipefd[0], buf.data(), buf.size())) > 0
  1. 下面給出的源代碼(注冊在sysprog1.c文件中)編譯后得到可執行文件(exe),如果用下面的命令行運行,stdout上的output會是什么? 這是為什么?

命令:sinavzorsayilmazdi

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM