- 论坛徽章:
- 4
|
先定义一个简单的模型:
任务1:一直收集东西,每收集一个,调用atom_inc对cc变量进行加1操作,并且对返回值进行判断如果大于等于10,就设置一个全局变量a为1通知另外的任务;
任务2:一直检测全局变量a,如果为1,则认为任务1已经收集到10个,然后调用atom_sub一次性消耗掉10个;
因此:
任务1:
while(1)
{
收集;
count = atom_inc(&cc);
if (count >= 10)
{
a = 1;
}
}
任务2:
while(a == 0);
atom_sub(10,&cc);
我们将任务1用汇编展开,并且仅在atom_inc前面采用一个mb,同时为了防止ll/sc的干扰(事实上跟cache一致性有关),我们用cc++代替:
while(1)
{
收集
mb()
reg = cc;
reg++;
cc = reg;
if(reg >= 10)
{
a = 1;
}
)
因为cc = reg;后面没有mb(),这里就隐藏了一个问题,a=1和cc=reg可能会乱序,就是说可能先执行a=1,然后执行了cc=reg。
当这种情况发生时,问题就会出来了,任务2发现a已经是1了,然后就进行了sub操作,就会出问题。
当atom_inc()后面增加mb后,就会将cc=reg和a=1两个进行强序化,任务2发现a=1的时候,cc必然被赋了新值。
实际运行的情况远比我说的复杂的多,但大概也就是这意思。 |
|