multithreading - 结构中带有变量的互斥锁
问题描述
我正在开发一个使用多个线程的项目,该线程可以访问包含多个变量的共享结构。
为了避免并发问题,每当对共享结构中的一个变量进行写入时,我都会使用互斥锁。现在我为每个变量使用不同的互斥锁,这样我就可以避免锁定一个线程来尝试写入一个没有被写入的变量,但我想知道是否有更好的方法来避免这个问题。
另外,考虑到我的结构有 uint16_t 变量,由于内存对齐和存储在同一数据寄存器上的多个变量,我应该采取什么额外措施来保证线程间的数据一致性?
谢谢。
解决方案
你没有说什么语言。我要假装它是C++。
我为每个变量使用不同的互斥锁......
这听起来很可疑。
您的线程通过更新共享状态相互通信。正确使用互斥锁会做两件事:
- 它确保在线程 A 更新共享状态后,其他线程将能够看到更改的内容,并且
- 它确保在更改完成之前其他线程不会看到更改。
如果线程可以通过写入单个uint16_t
值来有意义地更改程序的状态,那么您不需要互斥锁。只需将变量的类型更改为atomic<uint16_t>.
Make it atomic 即可确保其他线程可以看到更改。而且,您不必担心完整性。这很简单:每个其他线程都必须看到旧值或新值。没有其他可能。
mutex
当情况更复杂时,您需要一个。假设你有三个变量:
int a, b, c;
并且,假设有一条规则,它a+b+c
必须始终为零。像这样的规则称为不变量。现在,一个线程不可能合法地改变这三个变量中的一个。但是,如果它试图连续更改其中的两个,总是有可能其他线程可能会在错误的时刻查看它们,并且它可能会看到它们处于不一致的状态(即,处于破坏不变的。)
制作变量atomic
不会解决问题。而且,为每个变量创建一个单独的互斥锁 并不能解决问题。您需要一个互斥体,其目的是保护不变量。您需要每个更新a
,b
和/或c
的线程在进行更改时锁定该互斥锁;并且您需要每个期望不变量为真的线程在查看它们时锁定相同的互斥锁。
推荐阅读
- python - python(anaconda) 来自 php 的 exec()
- excel - 如何在Excel VBA中将单击的按钮BackColor格式化为黄色?
- python - Pathlib 使用“$”“规范化”UNC 路径
- perl - 如何使用 Perl 查找字符串中元音的数量
- javascript - 如何检查 NodeJS 中是否未定义某个属性
- asp.net - 设置特定条件时如何禁用aspx中的linkButton
- jmeter - 需要帮助捕获从 Jmeter 中的查看结果树采样器发送的 HTTP 请求
- c++ - C++ 向量和数组
- regex - 如何制作这个正则表达式
- laravel - `Row`1` 必须是 laravel 中的数组