用C++设计线程安全变量类
Design thread safe variable class in C++
我遇到了一个常见的问题(在这里发布了几个变体),一个进程运行多个线程,每个线程都可以读取或写入一组公共变量(为了简单起见,假设它是单个变量)。
每个变量都应该防止并行写入,并允许并行读取。
我已经看到了几个解决方案,并决定专注于下面一个使用保护(在这个链接中提到)
然而,我无法理解以下原则:
-
MutexGuard类:它不应该实现为singleton吗。否则,每个线程将创建新的互斥体,而不是等待单个公共互斥体。
-
如果类MutexGuard不是singleTon,那么至少m_Mutex应该是静态的,这样它将在该类的所有实例之间共享。
-
为什么函数1和函数2被定义为静态。这样就可以在没有实例上下文的情况下调用它(类只是名称空间),并且可能缺少m_SharedVar的值。
-
有什么简单的方法可以修改多读卡器/单写器锁的实现吗?在这种情况下,我应该只更改互斥对象类型吗?
class MutexGuard { MutexType & m_Mutex; public: inline MutexGuard(MutexType & mutex) : m_Mutex(mutex) { m_Mutex.lock(); }; inline ~MutexGuard() { m_Mutex.unlock(); }; } class TestClass { MutexType m_Mutex; double m_SharedVar; public: TestClass() : m_SharedVar(4.0) { } static void Function1() { MutexGuard scopedLock(m_Mutex); //lock the mutex m_SharedVar+= 2345; //mutex automatically unlocked } static void Function2() { MutexGuard scopedLock(m_Mutex); //lock the mutex m_SharedVar*= 234; throw std::runtime_error("Mutex automatically unlocked"); } }
我认为这里的问题是TestClass
。正如@TonyD正确指出的那样,MutexGuard
的实现不应该绑定到singleton,除非它是明确必要的。CCD_ 3的意图是执行CCD_;以自动方式为调用方指定互斥对象的unlock()
。因此MutexGuard
的调用者不必显式地lock()
或unlock()
。
现在,TestClass
负责保护互斥对象不受多重访问的影响。通常,如果每个函数都锁定了与类实例共享的互斥体,那么使用TestClass
函数的所有工作线程都将被自动保护。同样,它是具体实施的。所有实例可以有一个静态互斥,也可以有多个针对不同共享资源的互斥。
现在来谈谈你的问题
有什么简单的方法可以修改多阅读器的实现吗/单个写入程序锁定?在这种情况下,我应该只更改互斥对象类型吗?
你必须明白,多个读者/一篇文章是一个神话。它不能保证并行性。这只是意味着,锁定/解锁会根据需要更快。即,除非有人在写日期,否则多个读取器可以读取数据(假设值没有更改)。在这种情况下,您可能想要实现reader-writer
锁。
我的教授总是把mutex
锁称为胖锁。它并没有真正区分读/写,并且总是有恒定的锁定时间,无论您打算在共享资源上做什么工作。
欲了解更多信息,请参阅这篇stackoverflow帖子。或者,您也可以使用现成的BOOST读写器锁。
- 全局变量 多读取器 一个写入器多线程安全?
- 静态 constexpr 类成员变量对多线程读取是否安全?
- 在函数结束后使用指向变量的指针是否安全?
- C++线程安全:如果只有一个线程可以写入非原子变量,但多个线程从中读取. 会遇到问题吗?
- C++11如何在1个线程中使用条件变量处理2个线程安全队列
- C++:用IIFE线程初始化静态局部变量安全吗
- std::mutex作为一个成员变量对多个线程来说是安全的吗
- 为什么我的 std::atomic<int> 变量不是线程安全的?
- 将常量引用成员设置为临时变量是否安全
- 是局部unordered_map变量线程在C 中安全的线程
- 如何修复编译错误"此函数或变量可能不安全"(strcpy)
- 为什么静态局部变量的 MSVC 线程安全初始化使用 TLS
- 将自动类型变量初始化为零.这种类型安全吗?
- 定义,初始化全局const变量是安全的吗?
- 当空变量没有定义时,按值传递它们是否安全
- 使用函数模板中静态局部变量的地址作为类型标识符是否安全
- 如何使类静态变量线程安全
- 使用局部静态std :: ARNE_FLAG和局部静态指针对静态变量的线程安全初始化
- C++ - "本地时间" 此函数或变量可能不安全
- 用C++设计线程安全变量类