26
boost::posix_time::ptime parseDate(const std::string& format, const std::string& localDate)
{
    std::istringstream is(localDate);
    is.imbue(std::locale(is.getloc(), new boost::local_time::local_time_input_facet(format.c_str())));
    boost::posix_time::ptime pt;
    is >> pt;

    if (pt == boost::posix_time::ptime())
    {
        throw std::runtime_error("Parse error");
    }

    return pt;
}

この関数は、日付とフォーマット文字列とreturn boost::posix_time::ptime.

例:2012:06:14 02:50:58%Y:%m:%d %H:%M:%S.

ただし、マルチスレッドプログラムで呼び出すと、例外がスローされることがありますが、format正しくlocalDateて解析可能です (呼び出しごとに同じ日付を使用します)。std::stringstream/スレッドの問題について何かを見つけましstd::localeたが、最新のものはありません(gcc 4.6.3 64ビットを使用しています)。

ここで誰かが同じ問題を抱えています:

ここ数日間、Valgrind/drd を使用してテストを行ったところ、コードの多くの部分で問題が発生していることがわかりました。たとえば、いくつかのブースト日時変換関数を呼び出すときに、スレッドセーフではない std::locale() をヒットします。

問題のない更新されたコード:

boost::posix_time::ptime parseDate(const std::string& format, const std::string& localDate)
{
    std::istringstream is(localDate);
    auto* facet = new boost::local_time::local_time_input_facet(format.c_str());

    {
        boost::unique_lock<boost::mutex> lock(globalLocaleMutex);
        is.imbue(std::locale(is.getloc(), facet));
    }

    boost::posix_time::ptime pt;
    is >> pt;

    if (pt == boost::posix_time::ptime())
    {
        throw std::runtime_error("Parse error");
    }

    return pt;
}

それでも:なぜですか?

4

1 に答える 1

1

local_time への呼び出しがあることがわかります。基になるコードが localtime または localtime_r を呼び出すかどうかはわかりません。localtime を呼び出す場合、スレッドセーフではありません。localtime は結果を返すときに静的変数を使用すると思います。

于 2012-07-02T18:05:32.093 に答える