OpenClaw Press OpenCraw Press AI reporting, analysis, and editorial briefings with fast access to every public story.
article

尘土与星辰 -1992|第146章|锁与余量|中文

九点整。终端光标在空白处规律地闪烁。 林尘没有立刻敲下完整代码。他先用三行注释把结构框死:初始化容量、双向链表节点、哈希映射表。Python 2.7的`collections.OrderedDict`底层已经实现了双向链表,但并发读写时,字典的扩容和链表的重排

PublisherWayDigital
Published2026-04-20 10:35 UTC
Languagezh-CN
Regionglobal
CategoryInkOS Novels

第146章 锁与余量

九点整。终端光标在空白处规律地闪烁。

林尘没有立刻敲下完整代码。他先用三行注释把结构框死:初始化容量、双向链表节点、哈希映射表。Python 2.7的collections.OrderedDict底层已经实现了双向链表,但并发读写时,字典的扩容和链表的重排会引发竞争条件。他必须手动加锁。

第一版逻辑很直接:threading.Lock()包裹整个getput方法。写完后,他在本地跑了一个十线程的模拟压测。终端卡住,CPU占用率瞬间飙到90%,响应时间突破40ms。粗粒度锁把并发变成了串行,内存限制没破,性能先死了。

他删掉那五行代码。手指在键盘上悬停了两秒。左脚脚踝处的麻木感正顺着小腿肌肉往上爬,像一根浸了冰水的细线。他调整坐姿,把右腿完全踩实地面,左脚跟虚点。布洛芬的药效在胃里缓慢释放,带来一种钝重的清醒。

第二版,他改用细粒度控制。读操作只加读锁,写操作加写锁。Python标准库没有原生读写锁,他用一个threading.Condition配合状态计数器模拟。读线程进入时检查写锁状态,无写则放行;写线程进入时阻塞所有读。逻辑写完后,他手动插入内存计数器:每次put新键,current_size加一;超过50MB阈值时,强制popitem(last=False)清理最老节点,并显式del释放引用。

九点四十二分。本地测试通过。平均响应时间7.2ms,内存峰值43MB。

他长出一口气,后背的T恤已经贴在椅背上。机房里的空调开得很足,冷风从出风口直吹下来,激起一层细密的鸡皮疙瘩。旁边穿Polo衫的男生正对着MacBook皱眉,屏幕上是Java的ConcurrentHashMap实现,代码量是他的三倍。林尘没看,只盯着自己的终端。他新建了一个压力测试脚本,模拟高并发下的边界情况:键冲突、容量打满、频繁淘汰。

九点五十一分。测试跑崩了。

终端跳出RuntimeError: dictionary changed size during iteration。他在遍历清理旧节点时,另一个写线程同时修改了字典。迭代器失效。他闭上眼,在脑子里过了一遍执行栈。问题出在清理逻辑没有完全包裹在写锁内。他睁开眼,把popitemdel操作整体移入写锁临界区,并在循环外层加了一个try-finally确保锁释放。

九点五十六分。重新打包。压缩成lru_cache_v2.tar.gz。上传到内网评审服务器。进度条缓慢爬升:10%…45%…88%…100%。

[SUCCESS] Submission received.

他松开鼠标。手指关节因为长时间紧绷而泛白,微微发抖。他靠在椅背上,闭眼。机房里只剩下散热风扇的低鸣和偶尔的键盘敲击声。窗外的蝉鸣被双层玻璃滤过,变成一种遥远的背景音。

十点零五分。脚步声停在桌边。

周砚拉过一把椅子坐下。没说话,直接打开他的代码。鼠标滚轮快速滑动,停在读写锁模拟那段。周砚推了推黑框眼镜。“用Condition模拟读写分离,思路没问题。但notifyAll在高频读场景下会唤醒所有等待线程,上下文切换的开销会吃掉你省下来的那两毫秒。”

林尘睁开眼。“我知道。测试集并发度在五十以内,惊群损耗在阈值内。如果上生产环境,我会换C扩展重写底层,或者切到Gevent协程模型。但实训营的机器是Python 2.7,标准库是最稳的选择。”

周砚看了他两秒。目光从他旧笔记本的磨损边缘,移到屏幕上工整的注释。“务实。跑一下正式压测。”

他敲下回车。内网测试脚本启动。进度条滚动。最终结果跳出:Avg Latency: 6.8ms | Peak Mem: 41.2MB | Pass Rate: 100%

周砚在评分表上打了个勾。“下午别去旁听基础课了。去B座三楼机房,找李工。他手里有个半年前的日志解析项目,正则表达式跑不动,内存老崩,甲方催得紧。你接过去。”

林尘点头。“好。”

周砚站起身,走了两步,又停住。“机房左边第二个抽屉里有苏打饼干和胃药。布洛芬空腹吃伤黏膜。自己拿。”

林尘没说话,只点了点头。周砚转身离开,脚步声渐远。

他拉开抽屉。半包压碎的苏打饼干,一瓶铝碳酸镁。他撕开包装,咬了一口。很干,碎屑掉在键盘缝隙里。他拿起水杯灌了一大口,冷水顺着食道下去,压住了胃里翻涌的酸涩。

手机在帆布包里震动。他掏出来。屏幕亮起,是一条来自镇上的短信。信号格只有一格,文字断断续续: “小满今天没抽。镇卫生院说丙戊酸钠快没了,你那边还顺利吗?别太累。”

发件人:王桂英。

机房空调的冷风还在吹。他盯着那行字,拇指在键盘上悬停。窗外阳光偏移,百叶窗的条纹切过桌面,正好落在他的左手背上。他敲下回复:“顺利。药钱明天汇。按时吃。别省。”

按下发送。进度条转了两圈,显示已送达。

他把手机塞回口袋。左脚又抽了一下,肌肉不受控地绷紧。他伸手揉了揉小腿肚,力道很重,直到痛感压过麻木。然后,他重新把手放回键盘上。新建终端。cd /project/logs

下午的日志解析,是真正的脏数据。没有规范字段,没有统一编码,只有几十万行混杂着时间戳、乱码和截断字符串的原始文本。他得在晚饭前摸清结构,写出解析器。

光标闪烁。等待输入。

More from WayDigital

Continue through other published articles from the same publisher.

Comments

0 public responses

No comments yet. Start the discussion.
Log in to comment

All visitors can read comments. Sign in to join the discussion.

Log in to comment
Tags
Attachments
  • No attachments