gpt4 book ai didi

c++ - boost::format() 似乎不是线程安全的,因为 std::ctype::narrow() 不是线程安全的

转载 作者:行者123 更新时间:2023-12-02 06:52:33 37 4
gpt4 key购买 nike

我遇到了在多线程中使用 boost::format() 的问题。 boost格式库使用boost解析库,该库使用/usr/include/c++/4.8/bits/locale_facets.h中定义的函数std::ctype::narrow()(我使用的是G++版本4.8)。

narrow() 函数并不是很无害。实例变量_M_narrow是一个缓存。我发现跨线程该缓存是同时写入和读取的。必须锁定线程才能使用 boost::format 似乎很愚蠢,以至于避免使用 boost::format 这让我觉得我一定错过了一些东西。有谁对这个问题有更深入的了解吗?

  /**
* @brief Narrow char
*
* This function converts the char to char using the simplest
* reasonable transformation. If the conversion fails, dfault is
* returned instead. For an underived ctype<char> facet, @a c
* will be returned unchanged.
*
* This function works as if it returns ctype<char>::do_narrow(c).
* do_narrow() must always return the same result for the same input.
*
* Note: this is not what you want for codepage conversions. See
* codecvt for that.
*
* @param __c The char to convert.
* @param __dfault Char to return if conversion fails.
* @return The converted character.
*/
char
narrow(char_type __c, char __dfault) const
{
if (_M_narrow[static_cast<unsigned char>(__c)])
return _M_narrow[static_cast<unsigned char>(__c)];
const char __t = do_narrow(__c, __dfault);
if (__t != __dfault)
_M_narrow[static_cast<unsigned char>(__c)] = __t;
return __t;
}

最佳答案

_M_narrow 的定义是:

mutable char _M_narrow[1 + static_cast<unsigned char>(-1)];

实际上,并行写入/读取通常会存在危险,但在这种特殊情况下,据我所知,这很好。 (如有错误,请大家指正)

  • 数据结构是一个数组,如果写入(与 std::map 相反),它不会在结构上失效
  • 元素本身是一个char。写入 char 是所有主要处理器上的原子操作(与 intlongdouble 相反)<
  • 我看到的唯一竞争条件是检查缓存是否为空的 if 与对缓存的写入操作之间。但如果发生竞争,两个线程会并行评估 do_narrow,然后将相同的结果写入缓存。

我认为这涵盖了所有危险情况,这意味着该操作实际上是线程安全的,不需要锁定。

这种类型的实现的唯一问题是 clang 的线程清理器讨厌它,并且总是将其报告为潜在危险,即使它是安全的。

关于c++ - boost::format() 似乎不是线程安全的,因为 std::ctype<char>::narrow() 不是线程安全的,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51566505/

37 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com