Подтвердить что ты не робот

С++ Почему мой синтаксический анализ не является потоковым?

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 64bit).

Здесь у кого-то такая же проблема:

Тестирование за последние несколько дней с помощью 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;
}

Но все же: почему?

4b9b3361

Ответ 1

Я вижу, что есть вызов local_time. Я не уверен, что базовый код вызывает localtime или localtime_r. Если он вызывает localtime, то он не является потокобезопасным. Я считаю, что localtime использует статическую переменную, когда возвращает результат.