我正在學習 Linux 中的 PIPE,但遇到了一些我無法弄清楚的事情。我正在閱讀 rozmichelle 的博客http://www.rozmichelle.com/pipes-forks-dups/#pipelines。下面的代碼是對父行程通過PIPE傳遞給子行程的三個單詞進行排序。
#include <unistd.h>
#include <sys/wait.h>
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[]) {
int fds[2]; // an array that will hold two file descriptors
pipe(fds); // populates fds with two file descriptors
pid_t pid = fork(); // create child process that is a clone of the parent
if (pid == 0) { // if pid == 0, then this is the child process
dup2(fds[0], STDIN_FILENO); // fds[0] (the read end of pipe) donates its data to file descriptor 0
close(fds[0]); // file descriptor no longer needed in child since stdin is a copy
close(fds[1]); // file descriptor unused in child
char *argv[] = {(char *)"sort", NULL}; // create argument vector
if (execvp(argv[0], argv) < 0) exit(0); // run sort command (exit if something went wrong)
}
// if we reach here, we are in parent process
close(fds[0]); // file descriptor unused in parent
const char *words[] = {"pear", "peach", "apple"};
// write input to the writable file descriptor so it can be read in from child:
size_t numwords = sizeof(words)/sizeof(words[0]);
for (size_t i = 0; i < numwords; i ) {
dprintf(fds[1], "%s\n", words[i]);
}
// send EOF so child can continue (child blocks until all input has been processed):
close(fds[1]);
int status;
pid_t wpid = waitpid(pid, &status, 0); // wait for child to finish before exiting
return wpid == pid && WIFEXITED(status) ? WEXITSTATUS(status) : -1;
}
在上面的代碼中,父行程使用dprintf,但我想知道我們是否可以將父行程的標準輸出重定向到 PIPE 的輸入。所以我嘗試撰寫下面的代碼。
#include <unistd.h>
#include <sys/wait.h>
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[]) {
int fds[2];
pipe(fds);
pid_t pid = fork();
if (pid == 0) {
dup2(fds[0], STDIN_FILENO);
close(fds[0]);
close(fds[1]);
char *argv[] = {(char *)"sort", NULL};
if (execvp(argv[0], argv) < 0) exit(0);
}
// if we reach here, we are in parent process
close(fds[0]);
const char *words[] = {"pear", "peach", "apple"};
// write input to the writable file descriptor so it can be read in from child:
size_t numwords = sizeof(words)/sizeof(words[0]);
dup2(fds[1],STDOUT_FILENO);//redirect stdout
close(fds[1]); //fds[1] is not used anymore
for (size_t i = 0; i < numwords; i ) {
printf("%s\n", words[i]);
}
close(STDOUT_FILENO);
int status;
pid_t wpid = waitpid(pid, &status, 0);
return wpid == pid && WIFEXITED(status) ? WEXITSTATUS(status) : -1;
}
修正后,我使用了printf,據我所知,它將輸出到 STDOUT。但是,此代碼不列印任何內容,而第一個代碼列印如下:
apple
peach
pear
我不明白為什么會發生這種情況,是不是我理解錯了?
uj5u.com熱心網友回復:
根據手冊頁,dprintf是 POSIX 擴展,而不是標準庫函式,因此在可移植性方面并不等效。
就它們在 GLIBC 中的實作而言,printf和dprintf呼叫__vfprintf_internal,但請注意,dprintf這(done != EOF && _IO_do_flush (&tmpfil.file) == EOF)也建議在寫入后重繪 緩沖區。
printf,另一方面,沒有。
我會嘗試在標準輸出上擺弄緩沖,即setbuf,fflush或類似的東西,看看是否有幫助。
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/369516.html
