单词周围的互斥体读写

时间:2011-01-28 00:32:21

标签: embedded word mutex

如果你有一个多线程应用程序,在线程之间共享一个字变量(即 - 32位系统上的32位数据类型),是否有必要使用互斥锁来保护对该字的读写? / p>

2 个答案:

答案 0 :(得分:2)

通常,,您应该使用互斥锁同步访问权限。即使您认为对内存位置的写入是“原子”的,CPU也可能会重新排序读取和写入该内存的指令,从而导致不必要的行为。此外,在多核或多CPU系统上,如果没有同步,其他内核/ CPU可能无法立即看到对共享内存位置的写入。

有关更多信息,请参阅维基百科有关Memory Barrier的文章。

答案 1 :(得分:2)

而不是谈论缓存,多核,乱序执行等。我只是提供一个简单的例子来说明你为什么要使用互斥(或其他一些互斥技术,例如中断操作)等等。)

为了将变量递增1 - 至少在我处理的大多数架构中 - 你必须从内存中读取值到寄存器,调整寄存器中的值,然后将其写回内存。假设我们有2个线程,高优先级A和低优先级B.采取这种情况:

  • 线程B从存储器读取“x”到寄存器(值为5)。
  • 线程B将寄存器递增到值6。
  • 线程A先占线程B。
  • 线程A将“x”读入寄存器(值在内存中仍为5,对吗?)。
  • 线程A将寄存器增加到值6。
  • 线程A将值6写回内存
  • 线程A进入睡眠状态。
  • 线程B唤醒,并将其寄存器值6写回内存。

现在两个线程都增加了值,但它只增加了一个。

如果这是电梯楼层数,感知到的心跳次数,或航天飞机倒计时值(好的,那将是一个减量),我们可能会遇到问题。

请注意,有些架构(通常是CISC)可以原子地执行此增量操作,最好不要做出这个假设(hello,portability& correctness)。

注意:在某些情况下 - 但不要执行此操作 - 如果您有一位作家,则可以在没有互斥锁的情况下离开多个读者。例如,可能ISR增加了滴答计数或其他任何内容,其他线程/任务来自&经常阅读。

我想我想说的是保护共享数据总是一个好主意,即使你认为没有它也可以逃脱。如果你想“去突击队”,你真的必须知道你在做什么,即便如此,当它被移植到一个新的架构时,明天也会破坏相同的代码。