第一题(百度笔试题):
以下多线程对int型变量x的操作,哪几个不需要进行同步:
A. x=y; B. x++; C. ++x; D. x=1;
第二题:
一个全局变量tally,两个线程并发执行(代码段都是ThreadProc),问两个线程都结束后,tally取值范围。
inttally = 0;//glable
voidThreadProc()
{
for(inti = 1; i <= 50; i++)
tally += 1;
}
8 个解决方案
#1
第一题选d,因为这个操作可以用一条指令实现,是原子操作。
第二题最是50-100之间。
第二题最是50-100之间。
#2
x = 1;
50 100;
50 100;
#3
为什么x++不是?
还有,为什么是50----100 之间?
#4
我还以为是今天阿里的笔试题呢。。。有人分享就好了。。。
#5
x++有三条汇编指令
x内存入寄存器
寄存器自加1
寄存器数据放回内存x
多线程可以在这三条指令中间插入其它的指令的,这些指令如果对x有操作,显然结果就不可知了。
tally += 1
一样是分为三条指令,最坏的情况就是线程一读x,线程二也读x,线程一寄存器加一,线程二寄存器加一,放回
x,线程二放加x,这种情况虽然二个线程都对x加1,但显然只加了一次。所以到最后只加50次。
最好的情况就是线程一的for结束,再到线程二的for
一共执行100次
#6
x = 1;
50 100;
为什么x++不是?
还有,为什么是50----100 之间?
x++有三条汇编指令
x内存入寄存器
寄存器自加1
寄存器数据放回内存x
多线程可以在这三条指令中间插入其它的指令的,这些指令如果对x有操作,显然结果就不可知了。
tally += 1
一样是分为三条指令,最坏的情况就是线程一读x,线程二也读x,线程一寄存器加一,线程二寄存器加一,放回
x,线程二放加x,这种情况虽然二个线程都对x加1,但显然只加了一次。所以到最后只加50次。
最好的情况就是线程一的for结束,再到线程二的for
一共执行100次
#7
x = 1;
50 100;
为什么x++不是?
还有,为什么是50----100 之间?
x++有三条汇编指令
x内存入寄存器
寄存器自加1
寄存器数据放回内存x
多线程可以在这三条指令中间插入其它的指令的,这些指令如果对x有操作,显然结果就不可知了。
tally += 1
一样是分为三条指令,最坏的情况就是线程一读x,线程二也读x,线程一寄存器加一,线程二寄存器加一,放回
x,线程二放加x,这种情况虽然二个线程都对x加1,但显然只加了一次。所以到最后只加50次。
最好的情况就是线程一的for结束,再到线程二的for
一共执行100次
编译器不是有个优化吗?
volatile的问题,是防止编译器优化。
由于 我提供的代码里是没有volatile这个关键字,
你说,会不会因为 没有volatile 影响结果,导致结果最终不会在50---100 以内啊?
#8
x = 1;
50 100;
为什么x++不是?
还有,为什么是50----100 之间?
x++有三条汇编指令
x内存入寄存器
寄存器自加1
寄存器数据放回内存x
多线程可以在这三条指令中间插入其它的指令的,这些指令如果对x有操作,显然结果就不可知了。
tally += 1
一样是分为三条指令,最坏的情况就是线程一读x,线程二也读x,线程一寄存器加一,线程二寄存器加一,放回
x,线程二放加x,这种情况虽然二个线程都对x加1,但显然只加了一次。所以到最后只加50次。
最好的情况就是线程一的for结束,再到线程二的for
一共执行100次
编译器不是有个优化吗?
volatile的问题,是防止编译器优化。
由于 我提供的代码里是没有volatile这个关键字,
你说,会不会因为 没有volatile 影响结果,导致结果最终不会在50---100 以内啊?
已经分析了每次+1都有同时访问冲突和每次+1都没有访问冲突的情况。
你开不开优化都无关要紧了,不会跳出这两个极端情况的。
#1
第一题选d,因为这个操作可以用一条指令实现,是原子操作。
第二题最是50-100之间。
第二题最是50-100之间。
#2
x = 1;
50 100;
50 100;
#3
x = 1;
50 100;
为什么x++不是?
还有,为什么是50----100 之间?
#4
我还以为是今天阿里的笔试题呢。。。有人分享就好了。。。
#5
x = 1;
50 100;
为什么x++不是?
还有,为什么是50----100 之间?
x++有三条汇编指令
x内存入寄存器
寄存器自加1
寄存器数据放回内存x
多线程可以在这三条指令中间插入其它的指令的,这些指令如果对x有操作,显然结果就不可知了。
tally += 1
一样是分为三条指令,最坏的情况就是线程一读x,线程二也读x,线程一寄存器加一,线程二寄存器加一,放回
x,线程二放加x,这种情况虽然二个线程都对x加1,但显然只加了一次。所以到最后只加50次。
最好的情况就是线程一的for结束,再到线程二的for
一共执行100次
#6
x = 1;
50 100;
为什么x++不是?
还有,为什么是50----100 之间?
x++有三条汇编指令
x内存入寄存器
寄存器自加1
寄存器数据放回内存x
多线程可以在这三条指令中间插入其它的指令的,这些指令如果对x有操作,显然结果就不可知了。
tally += 1
一样是分为三条指令,最坏的情况就是线程一读x,线程二也读x,线程一寄存器加一,线程二寄存器加一,放回
x,线程二放加x,这种情况虽然二个线程都对x加1,但显然只加了一次。所以到最后只加50次。
最好的情况就是线程一的for结束,再到线程二的for
一共执行100次
#7
x = 1;
50 100;
为什么x++不是?
还有,为什么是50----100 之间?
x++有三条汇编指令
x内存入寄存器
寄存器自加1
寄存器数据放回内存x
多线程可以在这三条指令中间插入其它的指令的,这些指令如果对x有操作,显然结果就不可知了。
tally += 1
一样是分为三条指令,最坏的情况就是线程一读x,线程二也读x,线程一寄存器加一,线程二寄存器加一,放回
x,线程二放加x,这种情况虽然二个线程都对x加1,但显然只加了一次。所以到最后只加50次。
最好的情况就是线程一的for结束,再到线程二的for
一共执行100次
编译器不是有个优化吗?
volatile的问题,是防止编译器优化。
由于 我提供的代码里是没有volatile这个关键字,
你说,会不会因为 没有volatile 影响结果,导致结果最终不会在50---100 以内啊?
#8
x = 1;
50 100;
为什么x++不是?
还有,为什么是50----100 之间?
x++有三条汇编指令
x内存入寄存器
寄存器自加1
寄存器数据放回内存x
多线程可以在这三条指令中间插入其它的指令的,这些指令如果对x有操作,显然结果就不可知了。
tally += 1
一样是分为三条指令,最坏的情况就是线程一读x,线程二也读x,线程一寄存器加一,线程二寄存器加一,放回
x,线程二放加x,这种情况虽然二个线程都对x加1,但显然只加了一次。所以到最后只加50次。
最好的情况就是线程一的for结束,再到线程二的for
一共执行100次
编译器不是有个优化吗?
volatile的问题,是防止编译器优化。
由于 我提供的代码里是没有volatile这个关键字,
你说,会不会因为 没有volatile 影响结果,导致结果最终不会在50---100 以内啊?
已经分析了每次+1都有同时访问冲突和每次+1都没有访问冲突的情况。
你开不开优化都无关要紧了,不会跳出这两个极端情况的。