2011-09-06 3 views
30

C++은 struct tm "broken-down time"레코드가 필요한 strftime으로 시간 형식 지정 함수를 정의합니다. 그러나 C 및 C++ 03 언어는 이러한 레코드를 얻기위한 스레드로부터 안전한 방법을 제공하지 않습니다. 전체 프로그램에 대해 하나의 마스터 struct tm 만 있습니다.localtime_r에 대한 C++ 11 대체물

C++ 03에서는 언어가 멀티 스레딩을 지원하지 않았기 때문에 다소 좋았습니다. POSIX localtime_r과 같은 기능을 제공하는 멀티 스레딩을 지원하는 플랫폼 만 지원했습니다.

C++ (11)는 새로운 시간 유틸리티를 정의하는 글로벌 struct tm를 다시 초기화하는 데 사용될 것입니다 무슨입니다 비 고장난 time_t 유형에있는 인터페이스를 제공합니다. 그러나 time_t을 얻는 것은 문제가 아닙니다.

내가 빠진 것이 있습니까? 아니면이 작업은 여전히 ​​POSIX에 의존해야합니까?

편집 : 다음은 몇 가지 해결 방법 코드입니다. ::localtime_r을 제공하는 다중 스레드 환경 및 std::localtime 만 제공하는 단일 스레드 환경과의 호환성을 유지합니다. posix::localtime_r 또는 ::localtime_s 또는 what-have-you와 같은 다른 기능도 쉽게 확인할 수 있습니다.

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를 사용한다면 정의되지 않은 동작을 얻습니다. –

답변

17

아무 것도 없습니다.

다음 C 표준은 (아마도 올해 시판) 부속서 K에서 정의한 않습니다

struct tm *localtime_s(const time_t * restrict timer, 
         struct tm * restrict result); 

그리고이 새로운 기능은 스레드 안전합니다! 그러나 너무 행복하지 마십시오.

  1. localtime_s는 C11에 선택 확장 : 두 가지 문제가있다.

  2. C++ 11은 C11이 아니라 C99를 참조합니다. local_time_s은 C++ 11에서 찾을 수 없으며 선택 사항입니다.

업데이트 나는이 질문에 대답부터 4 년 동안

는 또한이 지역에있는 C++ 도구의 빈약 한 디자인에 의해 좌절되었다. 나는이 다루는 현대 C++ 도구를 만드는 동기가되었다

http://howardhinnant.github.io/date/tz.html

#include "tz.h" 
#include <iostream> 

int 
main() 
{ 
    using namespace date; 
    auto local_time = make_zoned(current_zone(), std::chrono::system_clock::now()); 
    std::cout << local_time << '\n'; 
} 

나를 위해이 단지 출력 :

2015년 10월 28일 14 : 17 : 31.980135 EDT

local_time은 현지 시간을 나타내는 std::chrono::system_clock::time_pointtime_zone의 조합입니다.

std::chrono::system_clock::time_point을 사람이 읽을 수있는 필드 형식 (예 : 연도, 월, 일,시, 분, 초 및 초 단위)으로 구분하는 유틸리티가 있습니다.https://www.youtube.com/watch?v=tzyGjOm8AKo

이 모든

이 (가 현대 C입니다 ++) 안전 물론 스레드입니다 : 여기 (비 시간대)을 중심으로 프리젠 테이션 조각이다.

+0

... 그리고 그들은 이름을 바 꾸었습니다! 정보 주셔서 감사합니다. 어쨌든,'localtime_r'이 사용 가능한지 여부를 질의하고, 그렇지 않으면'localtime'을 사용하는 것이 가능합니다. 그래서 나는 결국 내 케이크를 먹을 수있는 것처럼 보입니다. – Potatoswatter