You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

采用反证法证明含原子操作的C++多线程程序行为是否正确?

关于C++原子操作程序行为的证明正确性疑问

示例代码

#include <thread>
#include <atomic>

int main(){
  std::atomic<int> val = 0;
  std::atomic<bool> flag = false;
  std::jthread t1([&](){
     if(val.load(std::memory_order::relaxed) == 1){ // #1
       flag.store(true, std::memory_order::release); // #2
     }
  });
  std::jthread t2([&](){
    while(!flag.load(std::memory_order::acquire)); // #3
    val.store(1,std::memory_order::relaxed); // #4
  });
}

反证法证明过程

我尝试通过反证法证明该程序的行为:

首先,假设反事实情况:#3处的循环退出。

基于该假设前提,推导如下逻辑语句:

  • #3处循环退出 ⟾ #3读取自#2

    [stmt.while] p1:while语句中,子语句会重复执行,直到条件([stmt.pre])的值变为false。

  • #3读取自#2 ⟾ #2在程序生命周期内已执行

    [intro.races] p10:原子对象M的取值(由求值B确定)是由某个修改M的未指定副作用A存储的值,且B不先于A发生。

  • #2在程序生命周期内已执行 ⟾ #1处if语句的条件为true

    [stmt.if] p1:若条件([stmt.pre])为true,则执行第一个子语句;若存在else部分且条件为false,则执行第二个子语句。

  • #1处if语句的条件为true ⟾ #1读取自#4

应用假言三段论,可得出结论:

  • #3处循环退出 ⟾ #1读取自#4

此外,#3读取自#2意味着#2 happens-before #3,进而#1 happens-before #4,这说明#1无法读取自#4。由此可推导:

  • #3读取自#2 ⟾ ¬(#1读取自#4)

再次对第1条和第6条推导应用假言三段论,可得:

  • #3处循环退出 ⟾ ¬(#1读取自#4)

结合第5条和第7条推导,得出矛盾:

#3处循环退出 ⟾ ¬(#1读取自#4) ∧ (#1读取自#4)

即:

#3处循环退出 ⟾ False

注:符号⟾表示逻辑蕴含。

因此,矛盾说明假设前提不成立,#3处的循环无法在该程序中退出。

疑问

请问这种方法是否属于正确的正式证明方式?


内容的提问来源于stack exchange,提问作者xmh0511

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.02 04:42:28