2011-09-06 326 views
30

C++根據strftime定義時間格式化函數,這需要一個struct tm「分解時間」記錄。但是,C和C++ 03語言不提供線程安全的方式來獲取這樣的記錄;整個計劃只有一位主人struct tmC++ 11替代localtime_r

在C++ 03中,這或多或少都可以,因爲該語言不支持多線程;它只支持支持多線程的平臺,然後提供像POSIX localtime_r這樣的設施。

C++ 11還定義新的時間公用事業,其中接口與非破舊time_t類型,這是什麼將用於重新初始化全球struct tm。但獲得time_t不是問題。

我錯過了什麼或者這個任務是否仍然需要依賴於POSIX?

編輯:以下是一些解決方法代碼。它保持與多線程環境的兼容性,多線程環境提供::localtime_r和僅提供std::localtime的單線程環境。它可以很容易地適用於檢查其他功能,例如posix::localtime_r::localtime_s或什麼是你。

namespace query { 
    char localtime_r(...); 

    struct has_localtime_r 
     { enum { value = sizeof localtime_r(std::declval< std::time_t * >(), std::declval< std::tm * >()) 
         == sizeof(std::tm *) }; }; 


    template< bool available > struct safest_localtime { 
     static std::tm *call(std::time_t const *t, std::tm *r) 
      { return localtime_r(t, r); } 
    }; 

    template<> struct safest_localtime<false> { 
     static std::tm *call(std::time_t const *t, std::tm *r) 
      { return std::localtime(t); } 
    }; 
} 
std::tm *localtime(std::time_t const *t, std::tm *r) 
    { return query::safest_localtime<query::has_localtime_r::value>().call(t, r); } 
+0

難道你不能只是將'localtime'封裝在一個使用互斥體的函數中嗎?或者其他一些重量較輕的鎖?我不明白這裏需要POSIX。 –

+7

@尼科爾:是的,但只要沒有其他人試圖做同樣的事情,這是安全的。換句話說,它在一個程序中運行,而不是在一個庫中。 – Potatoswatter

+0

但是他們會從線程代碼中調用一個非線程安全的函數,所以他們會得到他們應得的。你可以公開一個函數供他們使用,如果他們使用標準的C函數,那麼他們會得到未定義的行爲。 –

回答