我知道strtol和strtof比atoi/atof更受歡迎,因爲前者檢測錯誤,並且strtol比atoi更靈活,當涉及非base-10時。我仍然對好奇:OS X上的'man atoi'(或atof)(儘管不是在Linux上!)提到atoi/atof並不是線程安全的。坦率地說,我很難想象atoi或atof的可能實現不會是線程安全的。有人知道手冊頁爲什麼這麼說嗎?這些功能在OS X或任何其他平臺上實際上是不安全的嗎?如果是這樣,爲什麼地圖庫不會僅僅根據strtol定義atoi,因此是安全的?爲什麼OSX文件atoi/atof不是線程安全的?
回答
在在MacOS X 10.6.6手冊頁以一看,它記錄了兩種功能,atof()
和atof_l()
,我懷疑,給出了一個提示,爲什麼功能被認爲不是線程安全:
概要
#include <stdlib.h> double atof(const char *str); #include <xlocale.h> double atof_l(const char *str, locale_t loc);
說明
的
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()
手冊頁不具有關於線程安全性或異步取消安全性的黃鼠狼字眼。然而,快速瀏覽一下strtol()
的源代碼顯示,它使用isspace()
,這是由區域設置的影響:
ISO/IEC 9899:1999,第7.11.1.1 setlocale函數
7.4中唯一不受當前語言環境影響的函數是isdigit和isxdigit。
(其中§7.4是<ctype.h>
。)
現在,雖然我不知道這個代碼是相同的什麼在達爾文(MacOS X系統),它很可能是相似的。我認爲手冊頁中可能存在勘誤的空間 - 目前尚不清楚需要更正的頁面是否爲atoi()
或strtol()
的頁面。
atoi()
這個問題的前提(在我編輯標題之前,它的原始形式)是錯誤的。它們是線程安全的。 POSIX指定所有函數都是線程安全的,除非另有說明(POSIX),並且文檔沒有說明這些函數不是線程安全的。 OSX聲稱符合POSIX,所以它們在OSX上是線程安全的,否則這是一個錯誤和主要一致性問題。我會認爲它只是在手冊頁中的一個錯誤...
一個猜測是這些函數沒有設置線程安全的方式errno,但這意味着一些奇怪的事情正在對馬科斯和errno進行和線。通常errno是一個線程局部變量。
經過一番研究,我認爲這只是遺留下來的舊時代errno
是一個全球變量。如果檢查的FreeBSD errno.h
history從first revision開始,你會看到,它最初被定義爲
extern int errno; /* global error number */
,現在它是一個功能。我真的無法想到任何其他原因。
雖然atoi
始終圍繞strtol
包裝,它也設置errno
,並應具有相同的線程安全性。它必須只是一個文檔問題。
Here's the implementation在蘋果的libc(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()
,你可能得出以下幾個結論中的一個或多個:
-
個
- 的文檔是錯
atoi()
是線程安全的, - 他們卻隻字不提,
strtol()
也是線程不安全, - 他們通過記錄該
atoi()
不作任何線程安全的承諾是保守的,即使當前實現恰好是線程安全的, - 他們是過時的(被錯誤的特殊情況,我想)
__current_locale()
返回指向描述線程的區域(不出所料)的結構。但是,如果尚未設置線程特定的區域設置,則返回指向全局區域設置結構的指針。我認爲與全球交易可能是線程不安全的,但這個問題也適用於strtol()
。
這個答案是在問題提出幾年後,第一次回答。在我的Mac OS X 10.8.3(大約2013年3月),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.
所以最後一句話是可能是從來就沒有在這裏一個線程安全的問題,只有在文檔中的錯誤。
- 1. EF上下文不是線程安全的,爲什麼不通過設計使線程安全?
- 2. 爲什麼std :: queue :: empty()不是線程安全的?不應該const函數是線程安全的?
- 3. 爲什麼我的代碼不是線程安全的?
- 4. 爲什麼Java的SimpleDateFormat不是線程安全的?
- 5. 爲什麼這個線程是不是安全
- 6. 什麼是線程安全的ByteArrayOutputStream?
- 7. 什麼是線程安全的對象
- 8. 爲什麼這個任務不是線程安全的?
- 9. 爲什麼閱讀不是線程安全的?
- 10. 爲什麼不可變對象是線程安全的?
- 11. 爲什麼JMS會話對象不是線程安全的?
- 12. 爲什麼此代碼不是線程安全的?
- 13. 爲什麼ReadOnlyDictionary不是線程安全的?
- 14. 爲什麼JPA EntityManager根據定義不是線程安全的?
- 15. 爲什麼地圖在C++中不是多線程安全的?
- 16. msdn:什麼是「線程安全」?
- 17. 線程安全是什麼意思?
- 18. 線程安全是什麼意思?
- 19. 爲什麼EJB線程安全並且servlet不是?
- 20. NSMutableDictionary不是線程安全的:那麼?
- 21. 爲什麼這個線程安全?
- 22. 用於PHP/WAMP的什麼是二進制文件 - 線程安全的/非線程安全的?
- 23. 什麼是使UnityContainer不是線程安全的缺陷?
- 24. 你是什麼意思Ruby on Rails不是線程安全的?
- 25. 「這個方法不是線程安全的」是什麼意思?
- 26. 如何以及爲什麼此代碼是線程安全的..?
- 27. 爲什麼這段代碼是可重入的,但不是線程安全的
- 28. 爲什麼我的線程安全代碼不工作?
- 29. C++不明白爲什麼這個代碼不是線程安全的
- 30. 如何使線程安全,而不是線程安全
有趣的問題... – ChristopheD 2011-01-07 23:48:49
大多數atoi實現只是strtol包裝它似乎。 – Anycorn 2011-01-07 23:54:43
我已更改此問題的標題,以便至少提供一個有效的問題。 – 2011-01-07 23:55:32