它本来应该是多少
场景:~/计数/计数.py 跑几次打印的数各不相同,没有一次是对的。对照表列了八个数。 任务:读代码,算出它「本来应该」打印的数(所有线程各加多少次的总和),到对照表里查那个数对应的标记。 可操作范围:只在分给你的这台实验机上操作。可以改家
哪个脚本有竞争
场景:~/脚本/ 里有三个多线程计数脚本,参数一样、最后都打印总数。只有一个有竞争条件。对照表列了八个文件名。 任务:找出有竞争的那一个(跑几次比结果,或者读代码找「读-改-写之间没有保护」的那个),到对照表里查它的文件名对应的标记。 可操
临界区在哪个函数
场景:~/计数/计数.py 是一个有竞争条件的多线程计数器。对照表列了八个函数名。 任务:找出「读共享变量、加一、写回」这三步所在的那个函数(临界区就在它里面),到对照表里查那个函数名对应的标记。调用它的线程函数和 main 都不算。 可操
加锁修好它
场景:~/计数/计数.py 是读-睡-写的计数器,每次打印的数都比期望值少。 任务:用 threading.Lock 把临界区保护起来,让它每次都打印期望值。规则:不许删 sleep、不许改线程数和次数、不许改成单线程——要靠锁修。修好运行
先检查、再动作,也要锁
场景:~/库存/卖.py:库存只有几件,更多的买家线程同时来买,每个先看「还有货吗」、有就减一。现在每次都超卖。 任务:用 threading.Lock 修好它,让它每次都打印「卖出 库存数」。规则:不许删 sleep、不许改库存和买家数。
让它稳定复现
场景:~/计数/计数.py 的加一明明是读-改-写,可跑几次都打印期望值——窗口只有几条指令,切换很少落进去。 任务:把它改成能稳定复现竞争的样子:在读和写之间加一个 time.sleep(0.001) 把窗口撑大,让它每次都打印一个小于期
交付:两处修好,写清临界区
场景:两个有竞争的程序要交付修好的版本:~/计数/计数.py(读-睡-写)和 ~/库存/卖.py(检查-再-动作)。 任务:都用 threading.Lock 修好(不许删 sleep、不许改参数);再写一个 ~/说明.md,写明 计数.p
多跑几次能证明什么
把一个多线程脚本跑 20 次,统计结果不一致的比例。这个数字【0】。
统计一串结果
真机上会拿到一串结果。算出总数、不一致次数、比例(整数百分比)、最小值: vals = [100, 100, 91, 100, 77, 100, 100, 100, 88, 100, 100, 100, 95, 100, 100, 100,
有几次不一致
场景:~/结果.txt 是把一个多线程计数器连跑 20 次的结果,一行一个;说明.txt 写了它本来应该每次打印的数。对照表列了八个数。 任务:数一数有几次不等于期望值,到对照表里查那个数对应的标记。 可操作范围:只在分给你的这台实验机上操