2011-01-07 5 views
15

मैं समझता हूं कि स्ट्रेटोल और स्ट्रॉफ को एटोई/एटॉफ को प्राथमिक पहचान त्रुटियों के बाद प्राथमिकता दी जाती है, और जब गैर-बेस -10 की बात आती है तो स्ट्रॉओल एटोई की तुलना में अधिक लचीला होता है।ओएसएक्स दस्तावेज़ atoi/atof क्यों थ्रेडसेफ नहीं है?

लेकिन मैं अभी भी कुछ के बारे में उत्सुक हूं: ओएस एक्स (हालांकि लिनक्स पर नहीं) पर 'मैन एटोई' (या एटोफ) का उल्लेख है कि atoi/atof थ्रेडसेफ नहीं हैं। मुझे स्पष्ट रूप से अटोई के संभावित कार्यान्वयन की कल्पना करने में कठिनाई होती है या उस पर जो थ्रेडसेफ नहीं होगा। क्या कोई जानता है कि मैन पेज यह क्यों कहता है? क्या ये कार्य वास्तव में ओएस एक्स या किसी अन्य प्लेटफ़ॉर्म पर असुरक्षित हैं? और यदि वे हैं, तो क्यों पृथ्वी पर लाइब्रेरी स्ट्रेटोल के मामले में एटोई को परिभाषित नहीं करेगी, और इसलिए सुरक्षित रहेंगी?

+3

दिलचस्प सवाल ... – ChristopheD

+0

अधिकांश एटोई कार्यान्वयन केवल स्ट्रेटोल रैपर हैं जो ऐसा लगता है। – Anycorn

+0

मैंने इस प्रश्न का शीर्षक बदल दिया है ताकि यह कम से कम एक वैध प्रश्न हो। –

उत्तर

3

MacOS एक्स 10.6.6 पर मैनुअल पृष्ठ पर एक नज़र ले रहा है, यह दो काम करता है, atof() और atof_l() दस्तावेजों, और मुझे लगता है कि यही कारण है कि समारोह थ्रेड-सुरक्षित नहीं समझा जाता है के रूप में एक संकेत देता है पर शक:

SYNOPSIS

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

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

वर्णन

atof() फ़ंक्शन स्ट्रिंग के प्रारंभिक भाग को स्ट्रेट से दोहरा प्रतिनिधित्व करने के लिए इंगित करता है।

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

दशमलव बिंदु चरित्र कार्यक्रम किसी भी स्थान (श्रेणी LC_NUMERIC) में परिभाषित किया गया है:

यह बराबर है।

जबकि atof() फ़ंक्शन वर्तमान लोकेल का उपयोग करता है, atof_l() फ़ंक्शन सीधे लोकेल को पारित किया जा सकता है। अधिक जानकारी के लिए xlocale (3) देखें।

कार्यान्वयन नोट्स

atof() समारोह थ्रेड-सुरक्षित है और यह भी नहीं async-रद्द-सुरक्षित नहीं है।

atof() फ़ंक्शन को strtod() द्वारा बहिष्कृत कर दिया गया है और इसे नए कोड में उपयोग नहीं किया जाना चाहिए।

त्रुटियों

समारोह atof() एक त्रुटि पर errno का मूल्य को प्रभावित जरूरत नहीं है।

मेरे संदेह है कि अगर वर्तमान स्थान एक और धागा द्वारा बदल दिया गया है, जबकि atof() समारोह निष्पादित हो रहा है, परिणाम की गारंटी नहीं है है। अन्यथा, चेतावनी के लिए कोई कारण नहीं लगता है।


मैं चारों ओर डार्विन सी पुस्तकालय स्रोत कोड की एक निश्चित स्थान के लिए poked है, लेकिन एक नहीं मिली है। आप atoi() के लिए FreeBSD स्रोत कोड में जाते हैं, यह स्पष्ट है समारोह कार्यान्वयन मामूली बात है कि:

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

(हाँ, यहाँ तक कि एक नमूने के परिभाषा का उपयोग नहीं है!)

strtol() के लिए आदमी पेज नहीं है थ्रेड सुरक्षा या async- रद्द सुरक्षा के बारे में weasel शब्द है। हालांकि, strtol() के लिए स्रोत कोड का शीघ्रता से अवलोकन से पता चलता है कि यह isspace() है, जो वातावरण से प्रभावित होता है का उपयोग करता है:

आईएसओ/आईईसी 9899: 1999, धारा 7.11.1.1 setlocale समारोह

7.4 में एकमात्र कार्य जिसका व्यवहार वर्तमान लोकेल से प्रभावित नहीं है, वह isdigit और isxdigit हैं।

(कहाँ §7.4 <ctype.h> के लिए है।)

अब, जबकि मुझे यकीन है कि इस कोड को क्या डार्विन (MacOS एक्स) में है के समान है नहीं कर रहा हूँ, यह समान होने की संभावना है। मुझे लगता है कि मैन पेजों में इरेटा के लिए कमरा हो सकता है - यह इतना स्पष्ट नहीं है कि जिस पृष्ठ को सुधार की आवश्यकता है वह atoi() या strtol() के लिए एक है।, के बाद से आदमी strtol strtol() के साथ एक धागे की सुरक्षा की समस्या का कोई जिक्र नहीं है

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

आप हो सकता है:

+0

'setlocale' फ़ंक्शन थ्रेड-सुरक्षित नहीं है और किसी अन्य थ्रेड को फ़ंक्शन में नहीं किया जा सकता है, जिसका व्यवहार लोकेल पर निर्भर करता है। हालांकि, ऐसे कार्यों को गैर थ्रेड-सुरक्षित समझा नहीं जाता है। एसिंक-रद्द-सुरक्षा के बारे में टिप्पणी भी अजीब लगती है, क्योंकि POSIX काफी स्पष्ट है कि 'pthread_setcanceltype',' pthread_setcancelstate', और 'pthread_cancel' को छोड़कर कोई फ़ंक्शन एसिंक-रद्द-सुरक्षित नहीं है। –

+0

यह बहुत समझ में आता है। यह बहुत बुरा है कि दस्तावेज़ अधिक विशिष्ट नहीं हैं कि जब तक आपका ऐप लोकेल नहीं बदल रहा है (मेरा निश्चित रूप से नहीं है) तब तक सुरक्षित है। मैं कोई लोकेल विशेषज्ञ नहीं हूं, लेकिन मुझे यकीन नहीं है कि मैं समझता हूं कि लोकेल का उपयोग एटोई में किया जाएगा (एटॉफ, मैं समझता हूं - दशमलव बिंदु)। –

+0

@ लैरी: 'atoi()' हजारों विभाजक और शायद समूह को देख रहा है, मुझे लगता है ... हालांकि, मेरे उत्तर में मेरा अपडेट देखें। –

-3

इस प्रश्न का आधार (इसके मूल रूप में, शीर्षक को संपादित करने से पहले) गलत है। वे थ्रेड-सुरक्षित हैं। POSIX निर्दिष्ट करता है कि सभी फ़ंक्शंस थ्रेड-सुरक्षित हैं जब तक कि अन्यथा दस्तावेज नहीं किया जाता है (POSIX द्वारा), और प्रलेखन इन कार्यों के बारे में कुछ भी नहीं कहता है जो थ्रेड-सुरक्षित नहीं है। ओएसएक्स पीओएसईक्स के अनुरूप होने के लिए purports, इसलिए वे ओएसएक्स पर थ्रेड-सुरक्षित हैं या नहीं यह एक बग और प्रमुख अनुरूपता मुद्दा है। मुझे लगता है कि यह मैन पेजों में बस एक बग है ...

+1

तो आपका जवाब' मैन एटोई 'ओएसएक्स पर गलत है? इससे इस प्रश्न का आधार गलत नहीं होता है। –

+1

हां। यह पहली बार नहीं होगा जब एक विक्रेता मैन पेज गलत है, या आखिरी। मुझे अभी भी पता नहीं है कि वे सिर्फ POSIX वाले लोगों के बजाय अपने स्वयं के मैन पेज लिखने पर जोर देते हैं ... –

+2

ओह, और मैं वह हूं जिसने प्रश्न का शीर्षक बदल दिया। मूल सवाल था "क्यों atoi/atof थ्रेडसेफ नहीं है?" –

0

एक अनुमान यह है कि ये फ़ंक्शन किसी थ्रेड सुरक्षित तरीके से इरनो सेट नहीं करते हैं, लेकिन इसका मतलब है कि मैको पर इरनो के साथ कुछ अजीब चल रहा है और धागा। आम तौर पर errno एक धागा स्थानीय चर है।

+4

आपको उस संस्करण को लिखने के अपने रास्ते से बाहर जाना होगा जो थ्रेड-सुरक्षित तरीके से 'errno' सेट नहीं करता है, क्योंकि बस' errno = foo; 'इसे सेट करने का एक बिल्कुल सुरक्षित तरीका है। –

+0

बूल के अलावा किसी भी चीज का आकलन आवश्यक नहीं है कि कंपाइलर विशिष्ट सीमाओं के बिना सी (या सी ++) में सुरक्षित थ्रेड सुरक्षित नहीं है –

1

कुछ शोध करने के बाद मुझे लगता है कि यह पुराने दिनों से केवल विरासत है जब errno एक वैश्विक चर था। आप FreeBSD errno.hhistory चेक करते हैं first revision से शुरू, आप देखेंगे कि यह मूल रूप से

extern int errno;   /* global error number */ 

परिभाषित किया गया था देखना चाहते हैं और अब यह एक समारोह है। मैं वास्तव में किसी अन्य कारण के बारे में नहीं सोच सकता।

हालांकि atoi हमेशा strtol के आसपास एक रैपर रहा है जो errno भी सेट करता है और उसके बाद एक ही थ्रेड सुरक्षा होनी चाहिए। यह सिर्फ एक दस्तावेज मुद्दा होना चाहिए।

+0

आधुनिक लिनक्स सिस्टम पर, इरनो थ्रेड-लोकल है, यानी प्रत्येक थ्रेड की अपनी प्रति है। –

2

atoi() की Here's the implementation एप्पल के libc में (atof() समान है):

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

और strtol() कई निष्कर्षों में से एक या अधिक ड्रा करें:

  • डॉक्स, atoi() धागे की असुरक्षित होने के बारे में गलत हैं
  • वे कहते हैं कि strtol() भी असुरक्षित थ्रेड है उल्लेख करने के लिए की उपेक्षा कर रहे हैं,
  • वे दस्तावेजीकरण कि atoi() धागा सुरक्षा का कोई वादा करता है के द्वारा रूढ़िवादी जा रहा है कर रहे हैं, भले ही वर्तमान कार्यान्वयन धागा सुरक्षित होने के लिए होता है,
  • वे पुराने हो चुके हैं (गलत होने का एक विशेष मामला है, मुझे लगता)

__current_locale() एक संरचना धागा भी स्थान (आश्चर्य) का वर्णन करने के लिए एक सूचक देता है। हालांकि, यदि कोई थ्रेड-विशिष्ट लोकेल सेट नहीं किया गया है, तो __current_locale() वैश्विक लोकेल संरचना में एक सूचक लौटाता है। मुझे लगता है कि वैश्विक से निपटना थ्रेड-असुरक्षित हो सकता है, लेकिन फिर वह समस्या strtol() पर भी लागू होगी।

+0

यह फ्रीबीएसडी संस्करण है। क्या यह मानने का एक अच्छा कारण है कि यह मैक ओएस एक्स पर समान है? –

+1

क्लिप http://www.opensource.apple.com/source/Libc/Libc-583 पर एक संग्रह से आए थे –

1

यह उत्तर प्रश्न पूछने के कुछ साल बाद है, और पहले उत्तर दिया गया। मेरी मैक ओएस एक्स 10.8.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. 

तो अंतिम शब्द शायद यहाँ एक धागे की सुरक्षा मुद्दा है, केवल दस्तावेज में त्रुटियों कभी नहीं था कि है ।

संबंधित मुद्दे