原子能(A&& B)?

时间:2013-01-25 11:40:54

标签: c concurrency atomic

有没有办法用连词制作原子if?也就是说,我可以以某种方式在C中以原子方式测试if(A && B)吗?如果它在第一个合并中短路那么这没有问题,但如果它没有问题,那么当它检查B时,A可能已经改变了。有什么想法吗?

编辑:不使用粗锁或信号量。

3 个答案:

答案 0 :(得分:4)

您必须手动同步对两个对象的访问!你还想怎么样?

这是并行编程的基本思想,一次可以发生两件事,除非你自己另外做。

伪代码样本:

//Comparison:
{
  lock(Amutex);
  lock(Bmutex);
  bool result = A && B;
  unlock(Amutex);
  unlock(Bmutex);

  if (result) // ...
}

//assignment:
{
  lock(Amutex);
  A = val;
  unlock(Amutex);
}

答案 1 :(得分:2)

如果在检查B之前绝对不能更改A,则可以在A上使用锁定/互斥(或其他同步原语,例如关键部分),如建议的那样。

您也可以加入A和B到一个单一的对齐的32位或64位整数,你会经常阅读并自动写入作为一个整体,再次,使用同步原语或CAS或特殊的CPU指令,因为它是有人建议。

如果您的系统是单处理器,您还可以在读取和写入A和B时禁止所有中断或调度以达到相同的效果。如果A或B可以由不同的CPU修改,这对多处理器系统不起作用。

如果您能够容忍A中的变化,并且只想在阅读B之后看到与读取B之前的A相同的A值,则可以读取A两次,B读取两次。必须注意确保读数的顺序。挥发性和/或记忆障碍有助于强制执行订单。

所有这一切都是针对目标硬件,操作系统和编译器的,如果不知道这些细节,就无法详细回答这个问题。

答案 2 :(得分:0)

使用mutexsemaphore来保护A免受更改。

或者你可以试试这个。

bool A_initial;
if( (A_initial = A) && B && (A==A_initial) ) {  /*A has not changed and 
                                                condition evaluated to true.  */
}
else if (A ! = A_initial){ /* You have to redo the if() or 
                              whatever if A is changed  */
}