簡體   English   中英

C - fdopen 為 STDOUT_FILENO 提供了一個 stream 不適用於 fflush

[英]C - fdopen gives a stream for STDOUT_FILENO that doesn't work with fflush

當我在 Linux 系統上運行以下 C 代碼時:

printf("This is sentence 1. ");
write(STDOUT_FILENO, "This is sentence 2.\n", 20);

我以錯誤的順序得到 output:

This is sentence 2.
This is sentence 1. 

我知道這是因為“printf”將數據發送到用戶空間中的緩沖區,並且需要一些時間才能到達 kernel 空間,而“write”將數據立即發送到 kernel 空間中的緩存緩沖區。

解決此問題的一種方法是通過以下方式將數據從用戶空間緩沖區刷新到內核空間緩沖區:

printf("This is sentence 1. ");
fflush(stdout);
write(STDOUT_FILENO, "This is sentence 2.\n", 20);

然后收到正確的 output :

This is sentence 1. This is sentence 2.

我嘗試解決此問題的另一種方法是嘗試從 STDOUT_FILENO fd 獲取標准輸出 stream:

FILE *file = fdopen(STDOUT_FILENO, "w");
printf("This is sentence 1. ");
fflush(file);
write(STDOUT_FILENO, "This is sentence 2.\n", 20);

但是,我得到的 output 順序錯誤:

This is sentence 2.
This is sentence 1.

為了確保 STDOUT_FILENO 是代表 stdout 的 fd,我將 stdout 轉換為 fd:

int fd = fileno(stdout);
if(fd == STDOUT_FILENO)
    printf("fd == STDOUT_FILENO == %d\n", fd);

並收到預期的output:

fd == STDOUT_FILENO == 1

所以,問題是為什么當將 STDOUT_FILENO 轉換為應該等同於標准輸出的 stream 時,'fflush' function 不起作用? 我使用“fdopen”的方式有問題嗎?

緩沖區是stdio stream的一個屬性,即FILE結構。 printf總是打印到stdout ,所以它是stdout stream 你需要調用fflush 當你寫

FILE *file = fdopen(STDOUT_FILENO, "w");`

,這給了你第二個,完全獨立的FILE stream,有自己的緩沖區。 但是您不會向該 stream 打印任何內容,因此fflush不會完成任何操作,同時,您打印到stdout的文本仍然未刷新。

如果您在stdout上有緩沖的fflush stdout (或者,或者,在您使用printf打印的字符串的末尾添加一個\n ,因為stdout通常是行緩沖的,至少如果它要去終端的話。)

在這:

FILE *file = fdopen(STDOUT_FILENO, "w");
printf("This is sentence 1. ");
fflush(file);
write(STDOUT_FILENO, "This is sentence 2.\n", 20);

printf不向file發送任何內容。 它寫入stdout

每個FILE object 都包含自己的緩沖區(直接或通過指向已分配內存的指針)。 當你執行printf("This is sentence 1. "); ,它寫入stdout FILE中的緩沖區。 當你fflush(file); ,它刷新file中的緩沖區。

要完成這項工作,您可以編寫fprintf(file, "This is sentence 1. "); ,因為這將寫入file中的緩沖區,並且fflush(file); 會沖洗它。

暫無
暫無

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

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