【问题标题】:Is there a way to ensure atomicity with an operation in C?有没有办法通过 C 中的操作来确保原子性?
【发布时间】:2010-12-10 21:18:02
【问题描述】:

我希望这个语句(在 if 语句的主体内)是原子的:

if(I2C1STATbits.P || cmd_buffer_ptr >= CMD_BUFFER_SIZE - 1)
    cmd_buff_full = 1; // should be atomic

我的处理器 (dsPIC33F) 支持原子位设置和清除。它还支持对 16 位寄存器和内存位置的原子写入;这些是单周期。我如何确定操作将以原子方式实现 - 有没有办法强制编译器执行此操作?在我的情况下,我相当肯定它会编译为原子的,但我不希望它在将来发生变化,例如,如果我更改一些其他代码并重新组织事物,或者如果我更新编译器。例如,是否有 atomic 关键字?

我正在使用 GCC v3.23 - 更具体地说,是 MPLAB C30,它是 GCC 的一个修改后的闭源版本。我正在研究一个只有中断的微控制器;没有线程的概念。原子性唯一可能的问题是,如果可能的话,可能会在两个周期的写入过程中触发中断。

【问题讨论】:

    标签: atomic


    【解决方案1】:

    根据您希望分配是原子的其他竞争操作,您可以使用sig_atomic_t。严格来说,这只保护它免受信号的影响。在实践中,它还提供了原子性。多层次。

    编辑:如果目标是保证存储操作不被编码为两条汇编指令,则必须使用内联汇编——C 不会在这方面做出任何保证。如果目标是防止中断干扰存储操作,另一种方法是在存储之前禁用中断,然后再启用它们。

    【讨论】:

    • 我不确定我的微控制器库是否提供此功能。
    • 所以你应该检查它是否有。
    • 我不这么认为。它不支持信号或线程。
    • 那为什么还需要原子操作呢?
    • @Martin v. Löwis:因为中断可能会中断两条指令之间的代码。
    【解决方案2】:

    不在 C 语言中,但可能在您的处理器随附的库中存在专有库调用。例如,在 Windows 上,有一个 InterlockedIncrement() 和 InterlockedDecrement()(用于 inc/dec longs),保证在没有锁的情况下是原子的。

    【讨论】:

    • 我认为我的微控制器没有。我的变量是 16 位的,所以我认为它是原子的,但我想确定一些优化不会改变这一点。
    猜你喜欢
    • 2019-09-03
    • 2013-05-10
    • 1970-01-01
    • 1970-01-01
    • 2015-08-27
    • 2016-07-13
    • 2021-09-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多