线程和读写内存是一个字节还是一点安全?

时间:2012-03-01 13:23:38

标签: multithreading performance

我想同步两个线程。目前我正在使用双锁旋转脏缓冲区与锁交换。

然而,我发现我只是这样做是为了防止在读取的同时发生写入的脏数据。我可以在最重要的位存储一个标志来传送数据吗?或者我甚至可以到整个字节。

例如,我可以拥有一系列这些并以bool的形式传达大量信息。读和写是线程安全的,因为硬件不能同时读写一个位。所以没有垃圾数据。

这可行吗?这是原子类型的全部概念。

3 个答案:

答案 0 :(得分:2)

您的两个线程之间仍需要某种同步。即使您确实使用了位,字节或字来指示数据是脏的,也无法保证缓冲区的其余部分同时更新。您仍然需要内存屏障来更新线程之间的缓冲区。

没有“原子阵列”这样的东西。您可以原子地读取和写入单个字节或单词,但是当您有两个字节或单词时,操作不是原子的。您的脏标志可以原子方式更新,但如果您有一个在线程之间共享的额外信息缓冲区,那么您需要同步以在另一个线程的内存中更新缓冲区。

此外,原子类型数组(volatileAtomic* 效率低,因为每次访问原子价值会导致内存障碍。使用现在的方式同步单个缓冲区和锁定效率要高得多。这样,可以一次更新单个(或多个)内存页面,而不是大量的小更新。

此外,在我认为你在这里的生产者/消费者模型中,消费者将需要wait()的东西,直到生产者完成并且生产者需要wait()得到的东西才能获得消费者丢弃的缓冲区。等待锁(或阻塞队列 - 见下文)是实现此目的的有效方法。

这里还要考虑其他一些事情,而不是

  • 使用一对blocking queues,以便消费者等待队列,然后将丢弃的缓冲区添加到丢弃队列。制片人会做相反的事情。
  • 您是否看过ByteBuffer

答案 1 :(得分:0)

这取决于您的处理器架构。如果您具有32位体系结构,那么如果您具有64位体系结构,则将运行32位值,然后运行64位值。如果使用在编程语言中使用的字节,位或16位字符数据类型,则无关紧要。除非它们小于或等于处理器的容量(32位或64位)。

答案 2 :(得分:0)

是的,我认为这可行,在测试你的标志时你想要进行原子测试并设置或比较和交换操作来设置指示写入发生的标志。您需要确保使用您的语言中的相应关键字(例如,可能是volatile或atomic),或使用某些操作系统提供的比较和交换功能。看看这个就是一个很好的例子:

http://drdobbs.com/embedded-systems/210604448?pgno=1