[英]C/C++ arrays with threads - do I need to use mutexes or locks?
我是使用线程的新手,并且已经阅读了很多关于如何共享和保护数据的内容。 但我也没有真正掌握使用互斥锁和锁来保护数据。
下面是我将要解决的问题的描述。 需要注意的重要一点是,这将是时间紧迫的,所以我需要尽可能地减少开销。
我有两个固定大小的双数组。
第一个数组将为后续计算提供数据。 线程将从它读取值,但它永远不会被修改。 某个元素可能会在某个时间被任何线程读取。
第二个数组将用于存储线程执行的计算结果。 这个数组的一个元素只会被一个线程更新,并且可能只有一次当结果值
是写给它的。
我的问题是:
每次访问只读数组中的数据时,我真的需要在线程中使用互斥锁吗? 如果是这样,你能解释一下原因吗?
当线程写入结果数组时,我是否需要在线程中使用互斥锁,即使这将是唯一写入该元素的线程?
我应该使用原子数据类型吗,如果我这样做会不会有任何显着的时间开销?
此类问题的许多答案似乎是 - 不,如果您的变量对齐,则不需要互斥锁。 我在这个例子中的数组元素会对齐,还是有什么方法可以确保它们对齐?
该代码将在 64 位 Linux 上实现。 我计划使用 Boost 库进行多线程处理。
几天来我一直在仔细考虑这个问题,并在整个网络上查看,一旦发布,答案和清晰的解释在几秒钟内就回来了。 有一个“接受的答案”,但所有的答案和评论都同样有帮助。
- 每次访问只读数组中的数据时,我真的需要在线程中使用互斥锁吗? 如果是,你能解释一下原因吗?
不会。因为数据永远不会被修改,所以不会有同步问题。
- 当线程写入结果数组时,我是否需要在线程中使用互斥锁,即使这将是唯一写入该元素的线程?
要看。
在任何情况下,请注意不要由不同的线程大量写入相邻的内存位置。 这可能会破坏性能。 参见“虚假共享”。 考虑到,您可能没有很多内核,因此没有很多线程,并且您说写入仅完成一次,但这可能不会成为一个重大问题。
- 我应该使用原子数据类型吗,如果我这样做会不会有任何重要的时间开销?
如果您使用锁(互斥),则不需要原子变量(并且它们确实有开销)。 如果不需要同步,则不需要原子变量。 如果您需要同步,那么在某些情况下可以使用原子变量来避免锁定。 在哪些情况下你可以使用原子而不是锁......我认为这更复杂,超出了这个问题的范围。
鉴于您在评论中的情况描述,似乎根本不需要同步,因此不需要原子或锁。
- ...在这个例子中我的数组元素是否会对齐,或者有什么方法可以确保它们对齐?
正如 Arvid 所指出的,您可以使用 c++11 中引入的alginas关键字请求特定对齐。 在 c++11 之前,您可以求助于编译器特定的扩展: https : //gcc.gnu.org/onlinedocs/gcc-5.1.0/gcc/Variable-Attributes.html
在给定的两个条件下,不需要互斥锁。 请记住,每次使用互斥锁(或任何同步构造)都是一种性能开销。 所以你想尽可能地避免它们(当然不影响正确的代码)。
不。不需要互斥体,因为线程只读取数组。
不可以。由于每个线程只写入不同的内存位置,因此不可能出现竞争条件。
不。这里不需要对对象进行原子访问。 事实上,使用原子对象可能会对性能产生负面影响,因为它会阻止优化的可能性,例如重新排序操作。
只有在共享资源上的数据被修改时才需要使用锁。 例如,如果一些线程用于写入数据而一些用于读取数据(在这两种情况下都来自同一资源),那么您只需要在写入完成时锁定。 这是为了防止所谓的“种族”。
当您制作在共享资源上操作数据的程序时,谷歌上有很好的种族信息。
你走在正确的轨道上。
1)对于第一个数组(只读),您不需要为其使用互斥锁。 由于线程只是读取而不是更改数据,因此线程无法破坏另一个线程的数据
2)我对这个问题有点困惑。 如果您知道线程 1 只会将元素写入数组插槽 1,而线程 2 只会写入数组插槽 2,那么您不需要互斥锁。 但是我不确定你是如何实现这个属性的。 如果我的上述陈述不适合您的情况,您肯定需要一个互斥锁。
3) 鉴于原子的定义:
原子类型是封装一个值的类型,该值的访问保证不会引起数据竞争,并且可用于同步不同线程之间的内存访问。
重点说明,互斥锁是原子的,这意味着只需要 1 条汇编指令即可获取/释放锁。 如果需要 2 个组装指令来抓取/释放锁,那么锁就不是线程安全的。 例如,如果线程 1 尝试获取锁并被切换到线程 2,线程 2 将获取锁。
使用原子数据类型会减少你的开销,但不会显着。
4)我不确定你如何确保你的变量是内衬的。 由于线程可以在您的程序中随时切换(您的操作系统确定线程何时切换)
希望这可以帮助
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.