gpt4 book ai didi

c++ - 如何以线程安全的方式初始化 C++ 全局互斥量

转载 作者:太空宇宙 更新时间:2023-11-04 12:42:28 24 4
gpt4 key购买 nike

尝试使用函数静态互斥体使代码线程安全。问题是并非所有编译器都以线程安全的方式初始化函数静态变量。

void Initialize()
{
static Mutex L; // can't be initialized at compile time because constructor calls CreateMutex()
L.Lock()
// call thread unsafe code
L.Unlock()
}

以下是已经考虑过的解决方案:

  1. 在全局范围内声明 Mutex,以便在 main() 之前进行初始化。不幸的是,当有一个全局变量的构造函数调用 Initialize() 时,这不起作用,因为在 C++ 中,无法保证全局变量的初始化顺序

  2. 使用原子操作


无效初始化()
{
静态 volatile uint16_t 锁=0;//可以在编译时进行简单的初始化
while (AtomicExchange(lock,(uint16_t)1)!=0);//与 1 交换锁并返回之前的值
//调用线程不安全代码
锁=0;
}

这可行,但缺点是忙等待

  1. 使用pthread的编译时初始化器

    pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;

不幸的是,这是针对 Windows 的,我们正试图避免使用 pthread

感谢便携的解决方案。我知道在 C++ 2011 中,函数静态初始化是线程安全的,但我们避免使用 C++ 2011,因为某些嵌入式平台可能对 C++ 2011 的支持不可靠。

最佳答案

IMO 解决您的问题的方法是使用漂亮的计数器惯用语。这个成语在这里有很好的描述:https://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Nifty_Counter .

使用这个习惯用法 std::coutstd::cerrstd::clog 流被初始化。唯一的要求是您需要正确计算创建类型的对齐方式。使用该对齐方式,您需要创建一个全局缓冲区。使用该缓冲区,可以创建具有放置新运算符的所需类型的实例。 Boost 和 Modern C++ (>= C++11) 具有 (std|boost)::aligned_storage 模板类来为您创建正确对齐的缓冲区。请引用:

现代版本的 C++ 具有 alignof 运算符,可用于计算特定类型的对齐方式。在 boost 中你需要使用类型特征 alignment_of: https://www.boost.org/doc/libs/1_69_0/libs/type_traits/doc/html/boost_typetraits/reference/alignment_of.html . alignment_of 类型特征也是现代 C++ 中 STL 的一部分,但在这种特殊情况下,alignof 运算符更易于使用。

关于c++ - 如何以线程安全的方式初始化 C++ 全局互斥量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53554033/

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