2011-01-07 6 views
15

나는 strtol과 strtof가 atoi/atof보다 선호된다는 것을 이해한다. 왜냐하면 전자는 오류를 감지하고, strtol은 non-base-10과 관련하여 atoi보다 훨씬 유연하다.OSX 문서 atoi/atof가 threadsafe가 아닌 것으로 나타나는 이유는 무엇입니까?

하지만 아직도 궁금한 점이 있습니다. OS X의 'man atoi'(또는 atof)는 atoi/atof가 스레드 안전하지 않다고 언급합니다. 솔직히 말하면 atoi 또는 atof의 구현이 스레드 안전하지 않다고 상상하기가 힘듭니다. 아무도 왜 맨 페이지가 이것을 말하는지 알고 있습니까? OS X 또는 다른 플랫폼에서 이러한 기능이 실제로 안전하지 않습니까? 그리고 그들이 존재한다면, 왜 지구상에 라이브러리가 strtol의 관점에서 atoi를 정의하지 않을 것이며, 따라서 안전할까요?

+3

흥미로운 질문 ... – ChristopheD

+0

대부분의 atoi 구현은 마치 strtol 래퍼입니다. – Anycorn

+0

이 질문의 제목이 적어도 유효한 질문이되도록 변경했습니다. –

답변

3

, 그것은 두 가지 기능 atof()atof_l()를 문서화하고, 그 함수가 스레드 안전하지 것으로 간주 이유에 대한 힌트를 제공합니다 의심 :

SYNOPSIS

#include <stdlib.h> 
double atof(const char *str); 

#include <xlocale.h> 
double atof_l(const char *str, locale_t loc); 

DESCRIPTION

atof() 함수는 str이 가리키는 문자열의 처음 부분을 double 표현으로 변환합니다.

 strtod(str, (char **)NULL); 

가 소수점 문자가 프로그램의 로케일 (카테고리 LC_NUMERIC)에 정의되어 있습니다 :에

은 동일합니다.

atof() 함수는 현재 로캘을 사용하지만 atof_l() 함수는 로캘을 직접 전달할 수 있습니다. 자세한 내용은 xlocale (3)을 참조하십시오.

구현 노트

atof() 기능은 스레드 안전 비동기 취소 안전하지도하고 있지 않습니다.

atof() 함수는 strtod()에 의해 사용되지 않으며 새 코드에서 사용하면 안됩니다.

에러

기능 atof() 오류에 errno의 가치에 영향을 미칠 필요가 없다.

내 의심은 atof() 기능이 실행되는 동안 현재 로케일이 다른 스레드에 의해 변경되는 경우, 결과가 보장되지 않는다는 점이다. 그렇지 않으면, 경고의 이유가없는 것 같습니다.


나는 Darwin C 라이브러리 소스 코드의 확실한 위치를 찾았지만 찾지 못했습니다. 당신이 atoi()에 대한 FreeBSD의 소스 코드에 갈 경우, 기능 구현이 사소한 것이 분명하다 :

int 
atoi(str) 
    const char *str; 
{ 
    return (int)strtol(str, (char **)NULL, 10); 
} 

(예, 심지어 프로토 타입 정의를 사용하지!)

strtol()에 대한 매뉴얼 페이지는하지 않습니다 실 안전 또는 비동기 취소 안전에 관한 족제비를 사용하십시오. 9899

ISO/IEC : 그러나, strtol()의 소스 코드 얼핏는 로케일에 의해 영향을 isspace(), 사용을 보여줍니다 1999 년 제 7.11.1.1은 setlocale 기능을

187 현재 로켈에서 동작이 영향을받지 않는 7.4의 유일한 함수는 isdigit 및 isxdigit입니다.

(§7.4이 <ctype.h>을위한입니다.) 이제

,이 코드는 다윈 (맥 OS X)에 무엇이 동일한 지 모르겠어요 동안, 유사 될 가능성이 높습니다. 맨 페이지에 정오표가있을 수 있다고 생각합니다. 수정이 필요한 페이지가 atoi() 또는 strtol()의 페이지인지 여부는 명확하지 않습니다.애플의 libc의

atoi()
+0

'setlocale' 함수는 스레드로부터 안전하지 않으므로 로케일에 따라 동작이 다른 함수에 다른 스레드가있을 수 있으면 호출되지 않을 수 있습니다. 그러나 이러한 함수는 스레드로부터 안전하지 않은 것으로 간주되지 않습니다. POSIX는'pthread_setcanceltype','pthread_setcancelstate','pthread_cancel'을 제외한 어떤 함수도 비동기 취소 안전하지 않기 때문에 async-cancel-safety에 대한 주석은 다소 이상하게 보입니다. –

+0

이것은 많은 의미가 있습니다. 문서가 로캘을 변경하지 않는 한 안전하다고 확신하지 못하는 점은 분명하지 않습니다 (물론 내 기능은 아닙니다). 저는 로캘 전문가는 아니지만 atoi (atof, 소수점)에서 로켈을 사용하는 방법을 잘 모르겠습니다. –

+0

@Larry :'atoi()'는 천 단위 구분 기호와 아마도 그룹핑을 보았을 것입니다. 그러나 내 대답은 내 대답을 참조하십시오. –

-3

제목을 편집하기 전에이 질문의 전제가 잘못되었습니다. 스레드로부터 안전합니다. POSIX는 (POSIX에 의해) 다르게 문서화되지 않는 한 모든 함수가 스레드로부터 안전하다는 것을 지정하며, 문서는 스레드 안전하지 않은이 함수들에 관해 아무 것도 말하지 않습니다. OSX는 POSIX에 부합한다고 주장하기 때문에 OSX에서 스레드로부터 안전합니다. 그렇지 않으면 버그와 주요한 적합성 문제입니다. 맨 페이지의 버그 일 뿐이라고 가정 할 것입니다 ...

+1

OSX에서 'man atoi'가 잘못되었습니다. 그렇다고해서이 질문의 전제가 잘못되지는 않습니다. –

+1

예. 공급 업체 매뉴얼 페이지가 잘못되었거나 마지막 페이지가 처음 나오는 것은 아닙니다. 나는 아직도 POSIX를 포함하지 않고 자신의 man 페이지를 쓰는 것을 왜 고집하는지 모르겠다. –

+2

오, 나는 질문의 제목을 바꾼 사람이다. 원래의 질문은 "왜 atoi/atof는 스레드 세이프가 아닌가?"였습니다. –

0

이 함수는 스레드 안전 방식으로 errno를 설정하지 않지만, 이상한 점은 macos 및 errno에서 이상하게 진행되고 있다는 것을 의미합니다. 실. 일반적으로 errno는 스레드 로컬 변수입니다.

+4

단순히'errno = foo;'가 완전히 안전한 방법이므로,'errno'를 thread-safe 방식으로 설정하지 않은 버전을 작성하는 것은 어려울 것입니다. –

+0

bool이 아닌 다른 것을 할당하는 것은 컴파일러 관련 확장이없는 c (또는 C++)에서 스레드 안전성이 반드시 필요한 것은 아닙니다 –

1

나는 약간의 연구를 한 후, errno이 글로벌 변수였던 옛날부터 단지 유산이라고 생각합니다. 당신이 first revision부터 FreeBSD의 errno.hhistory을 선택하면, 당신은 원래

extern int errno;   /* global error number */ 

로 정의 된 것을 볼 수있을 거라고 지금은 함수입니다. 나는 다른 어떤 이유도 생각할 수 없다.

비록 atoi은 항상 strtol의 래퍼이며 errno으로 설정되어 있으며 동일한 스레드 안전성을 가져야합니다. 문서화 문제 일뿐입니다. 맥 OS X 10.6.6을에 대한 매뉴얼 페이지에서 살펴보면

+0

최신 Linux 시스템에서 errno는 스레드 로컬입니다. 즉, 각 스레드마다 고유 한 복사본이 있습니다. –

2

Here's the implementation (atof() 비슷) :

int 
atoi(str) 
    const char *str; 
{ 
    return (int)strtol_l(str, (char **)NULL, 10, __current_locale()); 
} 

그리고 strtol() :

long 
strtol(const char * __restrict nptr, char ** __restrict endptr, int base) 
{ 
    return strtol_l(nptr, endptr, base, __current_locale()); 
} 

남자 strtol 함수가 strtol()와 스레드 안전 문제에 대한 언급을하지 않습니다 때문에, 당신은 수도 몇 가지 결론 중 하나 이상을 그려야합니다.

    (210)
  • 워드 프로세서는이 경우에도 atoi() 스레드 안전의 어떤 약속도하지 않습니다 것을 문서화하여 보수적있어 그들이 strtol()도 안전하지 않은 스레드 것을 언급 무시하고
  • ,
  • , atoi() 스레드 안전하지 않은 것에 대해 잘못 현재 구현은

__current_locale() 스레드의 로케일을 (당연히) 기술 구조에 대한 포인터를 반환

  • 그들은 오래된 것 (잘못되는 특별한 경우, 나는 가정), 스레드 안전을 위해 발생합니다. 그러나 스레드 별 로켈이 설정되지 않은 경우 __current_locale()은 전역 로캘 구조에 대한 포인터를 반환합니다. 전 세계를 다루는 것이 스레드가 안전하지 않을 수 있다고 생각하지만 그 문제는 strtol()에도 적용됩니다.

  • +0

    그건 FreeBSD 버전입니다. 그것이 Mac OS X에서 동일하다고 믿을만한 이유가 있습니까? –

    +1

    클립은 http://www.opensource.apple.com/source/Libc/Libc-583의 저장소에서 가져 왔습니다. –

    1

    이 답변은 질문이 제기 된 후 몇 년 후 처음 대답되었습니다. 내 맥 OS X 10.8.3에서 (3 월 2013 년 경) man atoi (또는 man atof)를 읽

    IMPLEMENTATION NOTES 
        The atof() and atof_l() functions are thread-safe and async-cancel-safe. 
    
        The atof() and atof_l() functions have been deprecated by strtod() and 
        strtod_l() and should not be used in new code. 
    

    그래서 최종 단어가 여기에 스레드 안전성 문제, 문서에만 오류가 결코 없다는 것을 아마 .

    관련 문제