【问题标题】:Atomic if(A && B)?原子 if(A && B)?
【发布时间】:2013-01-09 08:59:12
【问题描述】:

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

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

【问题讨论】:

  • 使用适当的同步对象。
  • 由于涉及多个汇编指令,您只能通过提供显式同步来使它们成为原子指令。即:将两条指令捆绑在一起作为一个逻辑单元,并在使用之前和之后应用锁(mutex or semaphore or ...)。
  • @Dervin 不要试图调节 cmets,而是专注于改进您的问题。平台?记忆模型?为什么你确定没有重新排序,你用volatile吗?诸如“将 A 和 B 作为两个字节保留在同一个对齐的机器字中,因此负载是原子的”之类的答案可能是答案,但不是您提供的那一点信息。
  • @Dervin:这一定是我在 StackOverflow 上见过的最粗鲁和短视的评论之一。
  • @DervinThunk 我真的不喜欢这个问题。对于问题的真正复杂性,指定的背景(机器,系统,任何东西)太少了。此外,正如 Anton 指出的那样,这个问题似乎没有什么意义,因为这些值的变化可能会在检查之后发生。

标签: c concurrency atomic


【解决方案1】:

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

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

伪代码示例:

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

  if (result) // ...
}

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

【讨论】:

  • 这应该是评论,因为它似乎没有提供实际答案。
  • @Paul R:Soo,那你认为什么是“实际答案”?有人为他/她做所有 OP 的工作?
【解决方案2】:

如果在您检查 B 之前绝对不能更改 A,您可以按照建议在 A 上使用锁/互斥锁(或其他一些同步原语,例如临界区)。

您还可以使用同步原语或 CAS 或特殊 CPU 指令将 A 和 B 连接成一个对齐的 32 位或 64 位整数,您始终可以原子地作为一个整体进行读写,因为它是被推荐了。

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

如果您可以容忍 A 的变化,并且只希望在读取 B 之后看到与读取 B 之前相同的 A 值,那么您可以读取 A 两次,然后再读取 B。必须注意确保读取的顺序。 volatiles 和/或内存屏障可以帮助执行命令。

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

【讨论】:

    【解决方案3】:

    使用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  */
    }
    

    【讨论】:

    • 更详细一点,也许一个例子可以使这个答案成为一个有用的答案。
    • @PaulR 您认为这将是一个合理的解决方案,因为问题的 OP 进行了编辑。
    • 我认为第二个建议行不通,正如你所说,OP 现在已经移动了球门柱。
    猜你喜欢
    • 2018-01-29
    • 1970-01-01
    • 1970-01-01
    • 2016-01-13
    • 2014-08-12
    • 2015-06-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多