对全局变量的多线程访问:我应该使用互斥锁吗?
Multithreaded access to global variable : should I use mutex
假设我有2个线程:std::thread thd1; std::thread thd2;
线程 thd1 周期性地设置一些全局变量调用以下setFlag
函数:
static std::int32_t g_flag;
static std::mutex io_mutex;
void setFlag( std::int32_t flag )
{
//std::lock_guard<std::mutex> lk(io_mutex);
g_flag = flag;
}
线程 thd2 定期读取此标志
std::int32_t getFlag()
{
//std::lock_guard<std::mutex> lk(io_mutex);
return g_flag;
}
问题是 - 在这种情况下我应该使用互斥锁吗?在没有互斥锁的情况下,从多个线程以读写方式访问变量是否安全?
访问一个线程中的写入和另一个线程中的读取或写入而不同步的内存位置,并且至少其中一个是非原子的,这称为数据争用,并导致C++中未定义的行为。
在代码中,对线程 1g_flag
的写入访问权限与线程 2 对同一变量的读取访问权限不同步。
因此,您的程序具有未定义的行为(因为没有任何访问是原子的(。
一种可能的解决方案是在注释代码中正确演示时使用互斥锁,这将同步读取和写入访问,以便一个发生在另一个之前,尽管这些发生之前的顺序仍然不确定。
另一种可能性是将g_flag
声明为原子:
std::atomic<std::int32_t> g_flag{};
如上所述,原子访问(std::atomic
提供(在可能并行访问以进行写入和读取时特别免于导致数据争用和未定义的行为。
原子(通常(不会像互斥锁/锁那样使另一个线程等待。但是,如果您还要访问其他共享内存,这也会使正确使用变得更加棘手。
相反,std::atomic
还有进一步的选项来指定是否以及如何对原子访问周围的其他内存访问进行排序,即它是否以及在多大程度上也会导致线程之间的同步。
如果没有进一步的细节,我无法确定在您的情况下合适的工具是什么。
相关文章:
- 为了方便起见,我应该避免公开私有字段变量吗
- 为什么我的全局变量似乎没有变化?
- C ++程序如何返回我的数组或写入全局变量
- 为什么我的数组值与此处的全局变量不匹配?
- 我应该如何在没有变量的情况下将相同的参数传递给 CMAKE 中的多个目标?
- 我应该使我的局部变量常量还是可移动的
- 对全局变量的多线程访问:我应该使用互斥锁吗?
- 主窗口应该是全局变量吗?
- C++我应该用什么来保存格式化为字符串变量(如sprintf())的文件
- 即使全局颜色发生变化,我应该如何让我的块保持其颜色?
- 我真的可以使用 Type 的每个声明创建一个全局变量吗?
- 为什么我的类函数不使用我的全局变量?
- 如何决定我应该使用全局变量还是应该使用堆
- C 我应该做什么而不是全局变量
- 我应该如何在我的C++项目中声明全局变量
- 为什么我的全局变量会引起问题
- 我应该为永远不变的值做一个全局常量变量吗,比如足球运动员的计数
- 为什么我的全局变量必须声明为指针
- 如何在循环外打印总和?我认为全局变量和局部变量的减速存在一些错误
- 我应该使用全局变量吗?