2011-09-06 330 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函数,那么他们会得到未定义的行为。 –

回答