【05-多处理器编程入门到放弃】课堂代码调试

lecture05是并发的第一节课。主要讲了入门(两个API,create和join)和放弃(原来很自然的串行想法)

并发线程模型

代码:
在这里插入图片描述
用mosaic检查(怎么将mosaic封装成命令行工具
在这里插入图片描述
(这里观察输出结果,会发现3消失了,5还重复了两次。)

最小线程库

thread.h是后续几乎所有例子都用到的头文件,可以将它放到固定位置,然后将路径放到环境变量中。(我没有,我改了后续例子的Makefile中的变量TLIB_PATH)

运行hello,发现ab交替的打印。top -d 0.5查看cpu使用情况,发现hello占用了将近200%的cpu。

这里有个问题,怎么占用率会大于1呢?
解答: % cpu 是表示单核 cpu 的占用率, 而不是占用所有 cpu 的占用率. 即如果我们是 8 核 cpu, 那么 800% 才是最高的 cpu 利用率。比如说有个程序App每个核心上都用了30%,那么看这个APP对应的CPU的使用率就是240%,机器总体的占用率只有40%。

在这里插入图片描述

线程自问自答

memory.c证明了T_a 和 T_b 真的共享内存。

stack.c证明线程具有独立堆栈 ,并且确定了堆栈的范围。

Makefile要做如下修改:
在这里插入图片描述
make后运行stack
在这里插入图片描述
运行memory
在这里插入图片描述
make run,可以运行两个。并且在这里把stack的输出取了最大值,可以看到每个线程堆栈空间是8K
在这里插入图片描述

1+1

在这里插入图片描述
就算sum++改成内嵌汇编也不行。(后续回顾:使用sum++结果不对的原因跟山寨支付宝一样。内嵌汇编结果不对的原因在于多处理器中每个处理器看到的sum不是同一个sum)

拓展:printf有一个缓冲区,跟多个线程同时修改sum的情况类似。好在printf是线程安全的。若否,当两个线程同时往缓冲区内加入内容时,你就会发现打印也打不对了。

思考题:3个T_sum线程,sum的结果最小是多少?

在这里插入图片描述

答案是2

弹幕:每个线程内部顺序不能被打乱, 但线程之间全局顺序可以交织,某个线程中最后一个循环不可能读到sum=0, 因为该线程前两个循环会保证sum!=0

2怎么来的:

=====       =====       =====
T1取0
			T2取0
T1加
T1存1
T1取1
T1加
T1存2
T1取2
T1加
T1存3
			T2加
			T2存1
T1取1
T1加
						T3
						……
						(结束)
			T2
			……
			(结束)
T1存2
(结束)
=====       =====       =====
结果:sum=2

通过这个例子,只能说人类 (我) 真不擅长理解并发

补充实验

当使用内嵌汇编并且是单处理器时,结果是正确的
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_45339670/article/details/143426162