C 识别干扰的可能性

C 识别干扰的可能性,c,real-time,interrupt,multitasking,rtos,C,Real Time,Interrupt,Multitasking,Rtos,在多任务环境中。如果任务的表达式为y=x+x是否有可能在x的两次读取之间发生中断(任务切换) 这里是针对类似x86的体系结构的一个特定答案,与传统的调度器()一起使用。看看这个asm代码,它是由gcc为x86生成的,优化设置为-OS0 转向 main: pushq %rbp movq %rsp, %rbp movl $5, -4(%rbp) movl -4(%rbp), %eax #read x

在多任务环境中。如果任务的表达式为
y=x+x是否有可能在x的两次读取之间发生中断(任务切换)

这里是针对类似x86的体系结构的一个特定答案,与传统的调度器()一起使用。看看这个asm代码,它是由gcc为x86生成的,优化设置为-OS0

转向

main:
        pushq   %rbp
        movq    %rsp, %rbp
        movl    $5, -4(%rbp)
        movl    -4(%rbp), %eax  #read x
        addl    %eax, %eax      #execute x + x
        movl    %eax, -8(%rbp)
        movl    $0, %eax
        popq    %rbp
        ret
正如您所看到的,x只读取一次,这意味着即使有任务切换,x上也不会有第二次读取


编辑: EOL在注释中指出,
x
确实可以读取两次,修改上述代码会产生以下结果:

volatile x = 5;
强制编译器插入两个movl操作(而不是一个):


但这并不意味着我的第一个猜测是错的。编译器将优化变量的读取访问(如果它是简单类型)并删除第二次读取。关键字强制编译器访问寄存器中的最新值。第一个代码不会强制读取-因此在线程切换和修改
x
的情况下会给出另一个结果。在大多数情况下,编译器生成的代码只读取x一次,因为优化非常简单。事实上,它甚至可能将操作转换为右移,相当于
x这只适用于一个特定硬件和软件的情况combination@M.M鉴于问题中没有说明硬件/软件组合,我假设这是一种流行且广泛使用的组合。考虑到上下文开关()总是几乎相同的事实。我可以对问题进行编辑,以明确说明这通常是无效的。这会不会让我的反对票消失?对其他反对票的回答:你能详细说明一下吗?我可以看出,我只讨论了一个特殊情况,它仍然回答了OP中的问题。C标准不保证
x
在这个表达式中只被读取一次。事实上,就抽象机器而言,
x
被读取两次(您可以通过
volatile
-限定
x
进行测试)。如果同时修改
x
,则行为未定义。@EOF:这是非常正确的。但是我们不应该失去注意力。OP询问这两次读取之间是否可能发生中断。我的第一个建议是,考虑到我们现有的代码,不会发生中断,因为只有一条movl指令。x的值发生的情况不在我们的范围内。声明x volatile将强制执行两条读取指令,因此这两条指令之间可能会发生中断。或者我完全陷入了这个问题?简单的回答是,如果
x
是一个被另一个线程同时修改的对象,和/或被信号处理程序异步修改的对象,并且
a
不是原子的,或者不是无锁原子的,或者是类型为
volatile sig_atomic_t
,在信号处理程序的情况下,行为是未定义的。在某些体系结构上,甚至不能保证使用单个原子指令可以获取单个
x
long-long
在a上,上述三条评论可以有效地阐述为答案-答案不应作为评论发布。合理使用评论可以解释为什么该问题值得否决-对我来说这似乎是一个合理的问题-尽管标题有些模糊。
volatile x = 5;
movl    -8(%rbp), %edx
movl    -8(%rbp), %eax