2013-08-19 23 views
2

在調用abort()以避免輸出丟失之前是否需要顯式刷新輸出流?C/C++:在異常終止之前刷新輸出

據我瞭解,有stderr沒有緩衝,輸出經過這麼叫abortstderr/cerr應該沒問題。 stdout/cout或我打開的文件如何?

PS。我在Linux環境下工作(如果有問題)。

回答

8

是的,它是必需的,但不是,它可能是不可能的。如果您從異步信號上下文中中止,則調用fflush會調用未定義的行爲。一般來說,如果調用abort的原因是您在程序中檢測到不一致的狀態,則存在stdio狀態也被破壞的風險,因此調用fflush是不安全的。

在一般情況下,你應該使用exit(1),如果你給你的程序根本無法處理的條件終止到期,並使用abort()(不fflush),只有當您發現您的程序調用未定義的行爲已經,

更多的細節:

C標準允許一個實現沖洗標準輸入輸出流作爲(C11 7.22.4.1 :)中止的一部分:

是否刷新具有未寫入緩衝數據的開放流,打開流是否關閉或刪除臨時文件是否是實現定義的。

但是,這並不能消除如果從信號處理程序調用abort工作的要求。因爲從實際的角度來看,如果從信號處理程序調用abort來刷新緩衝區通常是不可能的,因爲信號處理程序會中斷處於不一致狀態的緩衝區的stdio代碼,所以嘗試使用此配額的任何實現可能都是錯誤的。

abort Linux手冊頁的當前版本錯誤地指出:

如果中止()函數會導致進程終止,所有打開的流被關閉和刷新。

當前行爲的更正確的說法將是沖洗是嘗試但可能失敗或損壞數據。此錯誤是目前在被固定在glibc的過程(也許是修復已經承諾...?)根據這個線索:

http://www.sourceware.org/ml/libc-alpha/2013-05/msg00207.html

+0

是否僅中止刷新內核緩衝區,還是放棄用戶空間中的stdio緩衝區? – user2052436

+0

我正在用MPI和OpenMP線程編寫科學代碼。如果我遇到一個錯誤(通常與用戶輸入有關,或者一些運行時計算相關),我只想退出我的程序。我問最初的問題的原因是我希望我的日誌文件包含信息和錯誤descrption,在我的程序終止前被刷新。 因此,從你的回答來看,我不需要使用'abort','exit(EXIT_FAILURE)'就足夠了嗎? – user2052436

+0

@ user2052436:就可觀察到的行爲而言,內核緩衝區不存在。 –

0

Stdout是緩衝的,所以你打開的文件也是流的例子。您必須使用沖洗機械手明確沖洗它們。

+0

雖然這是真實的大部分時間,它_is_可能打開一個沒有緩衝的文件,我相信甚至有可能通過一些欺騙來獲得一個無緩衝的'stdout'。 – arne

+1

[一些欺騙](http://en.cppreference.com/w/cpp/io/manip/unitbuf)。 – BoBTFish

+1

只需在'main'的開頭使用'setvbuf'或'setbuf'來獲得無緩衝的'stdout'。 –