2012-03-09 75 views
3

假設我在多線程環境中調用函數時只記錄1個整數,那麼實現此機制的最佳設計是什麼?例如:什麼是記錄極少量數據的最有效方式?

void foo1() { 
    log(1); 
    ... 
} 
void foo2() { 
    log(2); 
    ... 
} 

以下是可能的方式:

  1. 只需登錄到使用fprintf()文件。 問題: 爲了記錄1個整數而調用 函數是不是一個昂貴的操作?糾正我,如果我錯了。
  2. 將記錄的整數存儲到數組緩衝區中;並定期刷新到文件中。 問題:如果線程崩潰,則進程將停止所有線程。所以可能,我可能會丟失很多最後的日誌信息。

對高效日誌記錄機制有何建議?

+0

不使用開源日誌框架的特殊原因? – 2012-03-09 14:06:34

+2

您應該首先擔心同步訪問日誌文件,這可能比性能更重要。 – 2012-03-09 14:07:59

+0

回覆@Als up,這裏是你可以/應該使用的C++日誌框架列表:http://stackoverflow.com/questions/696321/best-logging-framework-for-native-c – 2012-03-09 14:12:47

回答

0

你可以看一下日誌庫,比如boost日誌,或者看看用互斥鎖包裝std :: cout,cerr,cin(或者你也記錄的文件),因爲有緩衝,所以它不應該'不斷地寫入少量的文件。

+0

是不是'fprintf()'做同樣的事情? – iammilind 2012-03-09 14:13:01

+0

沒有我記得* printf都是線程安全的,但是它們也是無緩衝的,因此所有打印的內容都將被寫入文件(操作系統也可能會做一些緩衝),而流只在刷新時寫入或者當緩衝區被填滿但它們沒有線程安全時 – 111111 2012-03-09 14:20:33

2

那麼,「簡單」的日誌記錄不是。 fprintf將跳轉到內核(上下文切換),然後返回到程序(也是上下文切換)。速度不是很快,如果速度是你需要的。您可能還需要非常非常昂貴的sync()以確保日誌數據實際上在發生電源故障時將其存入磁盤。你真的不想去那裏:)

我想說,緩衝方法實際上是速度和可靠性之間最快和最合理的折衷。我要做的就是讓這個緩衝區同步,以便由多個線程安全地寫入。同時我會運行一個磁盤寫入器線程,它會偶爾刷新數據到磁盤(取決於您擁有的數據類型)。我會使用非常基本的語言功能,進入plain C土地,只是因爲某些功能(異常處理,多重繼承......)在特殊情況下太容易斷裂。

你可能不知道的一件事是,程序在崩潰時確實有發言權。您可以訂閱程序查殺signals(某些信號可以被程序取消,但是查殺信號不是其中之一)。在進行信號處理時,您可以最後一次刷新日誌緩衝區並保存更多數據。還有atexit()

+0

好的答案。所以根據你的第二種方法(在我的問題中)更好?另外,你提到的功能是平臺獨立的? – iammilind 2012-03-09 14:28:09

+0

是的,我認爲避免連續小寫入磁盤是一種更好的方法。不過,我認爲你還應該添加一些標識符來記錄哪些函數記錄了什麼(無法​​想象一個數字的用例,而沒有信息來自哪裏;)。是的,這些功能應該是跨平臺的,至少在nix方面,很可能也是windows。 – 2012-03-09 14:59:24

+0

啊,我看,整數是標識符。在那種情況下,如果可能的話,我實際上會建議一個真正的分析器。 – 2012-03-09 15:01:10

相關問題