返回信息流阿狸和桃子想去海边。阿狸想,如果桃子去,我就去。桃子想,如果阿狸去,我就去。
阿狸想,我还是问问桃子吧,不过,我觉得桃子肯定会去的。不如我先做一些旅行计划吧。他做了很多便笺,贴在电脑上,就去找桃子了。
桃子这样想,做了计划,贴了便笺,去找阿狸。
阿狸发现桃子不在,但是看到她电脑上贴着的详尽的旅行计划,他想,桃子肯定想去了。桃子看到阿狸的便笺,也肯定阿狸回去。
于是,他们就一起去海边了。
这个故事流传下来,包括计算机科学家也听说了这个故事。于是,下面这段c程序,在某些机器上偶尔会出现ali_go == taozi_go == 1
int ali_go=0, taozi_go=0;
// thread 1
int x = taozi_go;
if (x) ali_go = 1;
// thread 2
int y = ali_go;
if (y) taozi_go = 1;
这是一条镜像帖。来源:北邮人论坛 / cpp / #77011同步于 2014/2/19
该镜像源已超过 30 天没有更新,可能在源站已被删除。
CPP机器人发帖
阿狸和桃子的约会
nuanyangyang
2014/2/19镜像同步38 回复
订阅后,新回复会通过你的通知中心匿名送达。
9 条回复
呃。。
我以为是编译器对单个线程优化成了下面这个:
ali_go = 1;
if (!taozi_go) ali_go = 0;
看来想多了
【 在 nuanyangyang 的大作中提到: 】
: 这是处理器的问题。java也会这样
意思接近了。
【 在 KAITO 的大作中提到: 】
: 呃。。
: 我以为是编译器对单个线程优化成了下面这个:
: [code=c]
: ...................
差点没看见……
编译器什么也没做,是CPU内部的行为。你可以认为程序就是简单的:一次load,一次compare,一次branch,一次store。
【 在 KAITO 的大作中提到: 】
: 呃。。
: 我以为是编译器对单个线程优化成了下面这个:
: [code=c]
: ...................
个人感觉和数据区段的填充值有关系吧,用MinGW pthread模拟了下,不过没成功:
//
int a = 0, b = 0;
.bss:00407020 ds._a ; ?
.bss:00407024 ds._b ; ?
//
pthread_t tid_a, tid_b;
pthread_create(&tid_a, 0, func_a, NULL);
mov [esp+24h+var_18], 0
mov [esp+24h+var_1C], offset _func_a
mov [esp+24h+var_20], 0
lea eax, [ebp+var_10]
mov [esp+24h+var_24], eax
; 参数入栈
mov eax, ds:__imp__pthread_create
call eax ; __imp__pthread_create
//
void* func_a(void* arg){
int x = a;
if (x) b = 1;
return ((void*)0);
}
push ebp
mov ebp, esp
sub esp, 10h
mov eax, ds:_a ; int x = a;
mov [ebp+var_4], eax
cmp [ebp+var_4], 0
jz short loc_4016CE ; 等于0则跳
mov ds:_b, 1 ; b = 1;
loc_4016CE:
mov eax, 0
leave
retn
【 在 nuanyangyang 的大作中提到: 】
: 阿狸和桃子想去海边。阿狸想,如果桃子去,我就去。桃子想,如果阿狸去,我就去。
: 阿狸想,我还是问问桃子吧,不过,我觉得桃子肯定会去的。不如我先做一些旅行计划吧。他做了很多便笺,贴在电脑上,就去找桃子了。
: 桃子这样想,做了计划,贴了便笺,去找阿狸。
: ...................