Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/macos/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/user-interface/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 为什么不是';达尔文&x27;s strtod线程安全?_C++_Macos_Thread Safety_Darwin_Strtod - Fatal编程技术网

C++ 为什么不是';达尔文&x27;s strtod线程安全?

C++ 为什么不是';达尔文&x27;s strtod线程安全?,c++,macos,thread-safety,darwin,strtod,C++,Macos,Thread Safety,Darwin,Strtod,以下测试总是在我的“英特尔Mac Mini”上为我生成故障或总线错误 编译器: uname -a: Darwin vogon13 9.8.0 Darwin Kernel Version 9.8.0: Wed Jul 15 16:55:01 PDT 2009; root:xnu-1228.15.4~1/RELEASE_I386 i386 g++ -v: Target: i686-apple-darwin9 Configured with: /var/tmp/gcc/gcc-5493~1/src/

以下测试总是在我的“英特尔Mac Mini”上为我生成故障或总线错误

编译器:

uname -a:
Darwin vogon13 9.8.0 Darwin Kernel Version 9.8.0: Wed Jul 15 16:55:01 PDT 2009; root:xnu-1228.15.4~1/RELEASE_I386 i386

g++ -v:
Target: i686-apple-darwin9
Configured with: /var/tmp/gcc/gcc-5493~1/src/configure
--disable-checking -enable-werror --prefix=/usr --mandir=/share/man
--enable-languages=c,objc,c++,obj-c++
--program-transform-name=/^[cg][^.-]*$/s/$/-4.0/
--with-gxx-include-dir=/include/c++/4.0.0 --with-slibdir=/usr/lib
--build=i686-apple-darwin9 --with-arch=apple --with-tune=generic
--host=i686-apple-darwin9 --target=i686-apple-darwin9
Thread model: posix
gcc version 4.0.1 (Apple Inc. build 5493)
编译命令:

"g++"  -ftemplate-depth-128 -O3 -finline-functions -Wno-inline -Wall
-pedantic -g -no-cpp-precomp -gdwarf-2 -Wno-long-double -Wno-long-long -fPIC
-DBOOST_DATE_TIME_NO_LIB=1 -DBOOST_THREAD_NO_LIB=1 -DBOOST_THREAD_USE_LIB=1
-DDATE_TIME_INLINE -DNDEBUG  -I"." -c -o "strtod_test.o" "strtod_test.cpp"

"g++"  -o "strtod_test" "strtod_test.o"
"libboost_thread-xgcc40-mt-s.a" "libboost_date_time-xgcc40-mt-s.a"
-g -nodefaultlibs -shared-libgcc -lstdc++-static -lgcc_eh -lgcc -lSystem
-Wl,-dead_strip -no_dead_strip_inits_and_terms -fPIC
源代码:

#include "boost/thread/thread.hpp"
#include "boost/thread/barrier.hpp"
#include <iostream>

using namespace std;

void testThreadSafetyWorker(boost::barrier* testBarrier)
{
    testBarrier->wait(); // wait until all threads have started
    try
    {
        const char* str = "1234.5678";
        const char* end = str;
        double result = strtod(str, const_cast<char**>(&end));
        if (fabs(result-1234.5678) > 1e-6)
            throw runtime_error("result is wrong!");
    }
    catch (exception& e) {cerr << "Exception in worker thread: " << e.what() << endl;}
    catch (...) {cerr << "Unhandled exception in worker thread." << endl;}
}

void testThreadSafety(const int& testThreadCount)
{
    boost::barrier testBarrier(testThreadCount);
    boost::thread_group testThreadGroup;
    for (int i=0; i < testThreadCount; ++i)
        testThreadGroup.add_thread(new boost::thread(&testThreadSafetyWorker, &testBarrier));
    testThreadGroup.join_all();
}

int main(int argc, char* argv[])
{
    try
    {
        testThreadSafety(2);
        testThreadSafety(4);
        testThreadSafety(8);
        testThreadSafety(16);
        return 0;
    }
    catch (exception& e) {cerr << e.what() << endl;}
    catch (...) {cerr << "Unhandled exception in main thread." << endl;}
    return 1;
}

strod不是线程安全的。从来没有说过它是线程安全的。您应该使用strtod_l,它需要一个区域设置。在所有可能的情况下,有一个共享数据结构正在被它在线程代码中的使用所破坏

locale_t c_locale = newlocale (LC_ALL_MASK, "C", 0);
r = strtod_l(nptr, endptr, c_locale);
freelocale (c_locale);

您的代码对我来说很好(一旦我在
testThreadSafetyWorker
中的
catch(exception&e){…
行中添加了一个右括号)。当你遇到故障/总线错误时,gdb中的回溯看起来是什么样子?@Adam Rosenfield:谢谢你关于遗漏的大括号的注释,我已经修复了它。我假设你正在测试Darwin的某个版本:哪一个?如果没有,我知道其他平台工作正常,POSIX和MSVC。请参阅stack trace的更新问题。GCC 4.0.1可以追溯到2005年7月7日。T这是七年前的事了。仅供参考。我不认为strtod是线程安全的。一些实现明确声称它是线程安全的(例如MKS工具包)Posix需要任何没有明确地证明为非线程安全的函数来线程安全。参见IEEE STD1003.1-2008,XSH 2.91.实际上,我使用LoCaligyCasic导致了这个错误,而C++又使用C++流,而这又使用Strutod(至少在达尔文上)。。显然,我不是唯一一个认为它应该是线程安全的人!我知道它不能保证线程安全,但究竟为什么不能。:(为每个调用创建区域设置?词法转换还不够慢吗?;)在这个例子中,使用LoCaligaStudio或C++流的人做什么?@ Matt Chambers:使用一个现代编译器?<代码> Sttood 是编译程序的一部分。Strutod是GLYBC的一部分,IrrC。在不久前,库有一个修复,以确保它是线程安全的。也许这不是在达尔文的库副本中。@:我升级到llvm-gcc42,问题依然存在。这是MacPorts提供的最新Darwin编译器。下一步我将尝试vanilla GCC 4.4。有趣的是,微软的非现代编译器实现了这一点,而苹果的却没有。
strod
是线程安全的,或者至少posix要求它是线程安全的。如果它在Darwin上不是线程安全的,那就是在一个坏的操作系统中(还有另一个)一致性缺陷。。。
locale_t c_locale = newlocale (LC_ALL_MASK, "C", 0);
r = strtod_l(nptr, endptr, c_locale);
freelocale (c_locale);