[英]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 > 0
為true
,並且true
隱式轉換為整數值1
。
下一次迭代, read
應該返回一個非正數,結束循環。
當read
大小為1
時,其預期返回值與1 > 0
的結果無法區分。
將括號放在作業周圍。
(size = read(pipefd[0], buf.data(), buf.size())) > 0
命令:sinavzorsayilmazdi
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.