【问题标题】:Atomic execution of a statement block语句块的原子执行
【发布时间】:2017-05-29 16:44:11
【问题描述】:

我有一系列想要以原子方式运行的语句。为简单起见,假设它们包含在块语句中:

{
    // statements...
}   

在 C++14 中是否有任何直截了当的方法来做这样的事情?

为了澄清,我希望这个块被执行,就好像它只是一个原子操作一样。我没有要使用互斥锁保护的关键部分。问题是捆绑的操作应该一个接一个地执行,而不需要在序列中的第一条语句和最后一条语句之间进行多次上下文切换。

【问题讨论】:

  • 还没有。未来的计划。暂时使用std::unique_lock
  • @DeiDei 在未来的任何 C++ 中,如果没有实时内核的设施来防止原子块期间的中断和线程调度,这怎么可能?
  • @RichardCritten 看看N4514。它提出了synchronizedatomic 块。

标签: c++ c++11 visual-c++ c++14


【解决方案1】:

取决于您所说的“直截了​​当”。我认为std::unique_lock 使用起来非常简单。

{
    std::unique_lock lock(m_mutex);
    // sequence of operations

    // lock destructor will release mutex
}

唯一的问题是任何其他地方操作受互斥锁保护的变量必须做同样的事情。

编辑

回答明确的问题:

为防止上下文切换,您必须使用适当的实时操作系统 (RTOS),并使用其设施。如果您在 Linux 或 Windows 等通用操作系统下运行(visual-studio 标签建议后者),您可以进行各种特定于平台的调用,这将降低上下文切换的可能性 - 但您无法阻止它们。

(如果您在内核模式下运行,上下文切换的可能性会降低,但即便如此,也很难停止中断处理程序和页面错误处理程序的介入。)

【讨论】:

  • 你确定 OP 可以接受互斥而不是真正的原子性吗?
  • 不。但是true原子性会涉及到内核态(并且不在C++的范围内)
  • 感谢您的回答。我编辑了问题,请看一下。
  • @MartinBonner : 也许 才是真正的答案... ;-]
【解决方案2】:

问题是:事务性内存。事务是具有 原子性一致性隔离持久性 (ACID)属性的操作。 原子性:执行所有或不执行块的语句。 一致性:系统始终处于一致状态。所有交易都建立一个总订单。 隔离:每个事务与其他事务完全隔离运行。

“事务是一种投机行为,只有在初始状态成立时才会提交。与互斥锁相反,它是一种乐观的方法。事务在没有同步的情况下执行。只有在以下情况下才会发布它的初始状态不会发生冲突。互斥锁是一种悲观的方法。首先,互斥锁确保没有其他线程可以进入临界区。只有当它是互斥锁的独占所有者时,该线程才会进入临界区,并且,因此,所有其他线程都被阻塞了。” - Rainer Grimm

GCC 从 6.1 版开始支持事务性内存(需要 -fgnu-tm 才能启用)。 (reference)

【讨论】:

  • 通过回答 C++ 中事务内存支持的具体状态是什么(即仅在 technical specification stage),可以改进答案,并使其与 C++ 问题相关。看起来提议的synchronized 关键字将及时准确地回答这个问题,但目前它在标准中不受支持。那么这将是一个很好的答案。
  • @acraig5075 GCC 从 6.1 版开始支持事务内存(需要 -fgnu-tm 才能启用)。同步块的行为就像它们受到全局锁的保护,是不是事务,并且可能调用事务不安全函数。事务在没有同步的情况下执行。原子块有以下形式:atomic_noexceptatomic_commitatomic_cancel。三个后缀_noexcept, _commit_cancel 定义了原子块应如何管理异常(reference)
  • 你说的一切都很好,我不是在争论。我说的是编辑问题并添加 C++ 相关性。我已经为你添加了这个。
  • 感谢您的意见。我赞成它,但它需要一个代码 sn-p 被接受作为答案。再次感谢您。
猜你喜欢
  • 1970-01-01
  • 2021-12-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-06-25
  • 1970-01-01
  • 2014-08-23
  • 1970-01-01
相关资源
最近更新 更多