30
C++根據strftime
定義時間格式化函數,這需要一個struct tm
「分解時間」記錄。但是,C和C++ 03語言不提供線程安全的方式來獲取這樣的記錄;整個計劃只有一位主人struct tm
。C++ 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); }
難道你不能只是將'localtime'封裝在一個使用互斥體的函數中嗎?或者其他一些重量較輕的鎖?我不明白這裏需要POSIX。 –
@尼科爾:是的,但只要沒有其他人試圖做同樣的事情,這是安全的。換句話說,它在一個程序中運行,而不是在一個庫中。 – Potatoswatter
但是他們會從線程代碼中調用一個非線程安全的函數,所以他們會得到他們應得的。你可以公開一個函數供他們使用,如果他們使用標準的C函數,那麼他們會得到未定義的行爲。 –