2010-01-11 37 views
4

我讀過一個手冊頁,當exit()被調用時,所有的流自動刷新和關閉。起初,我對這是如何完成以及它是否真的可靠,但看到我再也找不到我會接受它的作品 - 我們會看看是否有什麼事情會爆炸的問題持懷疑態度。無論如何,如果這種流關閉行爲出現在exit()中,這種行爲也存在於SIGINT的默認處理程序中(中斷信號通常由Ctrl + C觸發)?或者,是否有必要這樣做:C語言開放流自動刷新並關閉SIGINT?

#include <signal.h> 
#include <stdlib.h> 

void onInterrupt(int dummy) { exit(0); } 

int main() { 
    signal(SIGINT, onInterrupt); 
    FILE *file = fopen("file", "a"); 
    for (;;) { fprintf(file, "bleh"); } } 

要得到file要正確關閉嗎?或者可以安全省略signal(SIG...void onInterrupt(...行嗎?

請限制對C,C99和POSIX的回覆,因爲我沒有使用GNU libc。謝謝。

+1

它絕對封閉。所有文件描述符在流程結束時被釋放。我不確定他們是否被刷新。 – 2010-01-11 19:36:25

回答

7

的C99規格7.19.3具有較弱的保證:

5如果主 函數返回到原來的調用者,或者退出函數被調用,所有打開的文件被關閉(因此所有的輸出在程序終止之前流被刷新)。程序終止的其他路徑,如調用中止函數,不需要正確關閉所有文件 。

4通過關閉文件,可以從控制流中取消關聯文件。輸出流 在 之前被刷新(任何未寫入的緩衝區內容被傳輸到主機環境),該流與文件分離。

所以在C99中,如果它關閉,那麼它會被刷新。

POSIX exit function有更多的細節,特別是_exit是否關閉流是實現定義的。

6

如果您希望刷新緩衝區,則必須處理該信號。否則,進程將被終止並且文件描述符關閉而不刷新stdio緩衝區。

+1

這是正確的。默認情況下,一個SIGINT將終止進程* abnornally *。如此終止的進程不會調用exit(),因此沒有刷新緩衝區。 – 2010-01-11 19:52:03

+0

你怎麼知道這個? – 2010-01-11 20:22:45

+1

幾乎在所有情況下,來自信號處理程序的刷新緩衝區都會調用未定義的行爲。唯一的辦法是,如果你能確保在信號發生時不能執行異步信號不安全的功能。 – 2011-03-22 05:49:00