int i=5;
f()
{
i++;
i--;
}
对于上面的代码,如果三个线程同时执行上述函数f()
,那么全局变量i
的总差值是可能的呢?
注意:i
初始化为5全球。
答案 0 :(得分:10)
我会说这是组合学中的一项练习,我个人不打算这样做,但我确实想明确这是 NOT 正确的方法让线程执行这个{{ 1}}。问题是f()
的实现不是单个指令,这意味着在对operator++
的一次调用中途,它可以进行上下文切换并在另一个线程中执行另一个operator++
。这将导致变量f()
的损坏状态。
因此,在没有正确同步的情况下确定i
的可能值是没用的,因为它可能是任意数量的值,真实的或不真实的,因为事情可能会腐败。
答案 1 :(得分:6)
假设++运算符被定义为指令:
1) Load the memory location holding i into register A. 2) Add one to the value stored at register A. 3) Store register A back into memory holding i."
现在我们有3个线程,因为没有同步工具,所以无法保证操作系统何时在这些线程之间进行上下文切换。
所以这是一种可能的情况。
1)线程1将i加载到寄存器A中。寄存器A保持值5。
2)线程1在寄存器A中加1。寄存器A现在保持值6。
3)OS上下文切换到线程2.
4)线程2将i从内存加载到寄存器A 中覆盖之前的值。寄存器A现在保持值5.
5)线程2向寄存器A添加一个。注册A现在再次保持值6.
6)线程2将寄存器A存储回变量i的存储器中。我持有值6.
7)OS上下文切换回线程1.
8)线程1从它停止的地方继续,将寄存器A存储回变量i的存储器中。我仍然保持值6。
这里我们已经“成功”运行了两个完整的增量运算符,并且只导致向变量添加一个值。哦,多线程的危险......
答案 2 :(得分:2)
该程序具有无限多种可能的结果(即使int
变量只有有限的许多可能值),因为它通过从多个线程访问同一对象而没有同步来调用未定义的行为。
我认为你的导师想要一个基于组合学的小答案,但是根据C语言错了。
答案 3 :(得分:0)
这是作业吗? 我认为3到7之间的任何整数值都是答案。
如果你打开优化,我希望我不会被任何线程实际改变。
答案 4 :(得分:0)
i
, 00000000 00000000 00000000 00000000
可以从11111111 11111111 11111111 11111111
转到int32
。
你去。