尘土与星辰 -1992|第149章|偏移量与锁|中文
凌晨两点四十分。宿舍楼彻底安静,只有走廊尽头饮水机偶尔发出“咕噜”的加热声。林尘盯着屏幕上的架构图。光标在“进程间通信”模块闪烁,像心跳。 Python 2.4的GIL锁是绕不开的墙。`os.fork`能复制进程,但父子进程间的管道通信在数据量大时极易阻塞。他
第149章 偏移量与锁
凌晨两点四十分。宿舍楼彻底安静,只有走廊尽头饮水机偶尔发出“咕噜”的加热声。林尘盯着屏幕上的架构图。光标在“进程间通信”模块闪烁,像心跳。
Python 2.4的GIL锁是绕不开的墙。os.fork能复制进程,但父子进程间的管道通信在数据量大时极易阻塞。他需要把两百万行日志切块,每块五万行,由子进程独立解析,结果回传。内存峰值必须压住。他新建一个文本文件,开始画数据流向。主进程负责分发文件偏移量,子进程读取、正则匹配、状态码分类,写入临时文件。主进程最后按序合并。不用共享内存,避免2.4下multiprocessing模块的兼容性陷阱。
他敲下第一版伪代码。def worker(pipe, offset, chunk_size): 逻辑清晰,但细节是魔鬼。管道缓冲区默认只有4KB,高并发下写操作会挂起。他必须在子进程里加非阻塞写入,或者改用文件描述符直接映射。他翻出实训营发的《Linux系统编程》手册,纸质版,书脊已经开裂。第14章,管道与FIFO。他逐字看,手指在桌面上无意识地敲击。左脚在拖鞋里又抽了一下,肌肉僵硬得像块风干的木头。他站起来,扶着桌沿慢慢走两步,血液回流带来一阵细密的刺痛。他坐下,继续。
把管道改成临时文件加文件锁。fcntl.flock。2.4支持。写入临时文件,主进程按序读取合并。内存占用从线性增长变成常数级。他打开终端,用dd命令生成一个五十万行的模拟日志文件,跑了一遍原型。终端滚动,CPU占用率瞬间飙到85%。三秒后,输出结果。他拉出系统监控器。内存峰值21.4MB。耗时4.1秒。线性推算,两百万行会在16秒左右跑完,内存不会超过28MB。远低于50MB的红线。李工要求的是300毫秒每万行,也就是总耗时控制在60秒内。16秒看似达标,但生产环境有网络IO和磁盘读写开销,必须留出余量。
他盯着终端里滚动的日志。瓶颈在文件锁竞争。四个子进程同时尝试获取锁,上下文切换消耗了太多CPU周期。他需要更底层的调度。Linux 2.6内核支持epoll,但实训营分配的开发镜像权限受限,用户态库也不完整。他不能在第一版文档里假设所有节点都能直接切到最佳内核路径。他翻到手册第22章,I/O多路复用。select和poll。2.4也兼容。他决定用poll替换文件锁的轮询逻辑,把临时文件改成内存映射mmap。减少系统调用次数。
屏幕右下角跳到05:15。窗外泛起灰白,云层很厚,像浸了水的棉絮。他保存文档,命名为arch_v1_draft.txt。手机屏幕亮起。王桂英的短信:“电修好了。村医说小满的药得换牌子,原来的断货。新牌子一盒贵十二块,得先交钱。你那边忙,不用回。”
林尘盯着“贵十二块”。他打开网银界面。余额1112.4元。实训营的饭卡里还有四十多块。他转了三百块过去。备注:买药。手续费扣了两块。余额变成810.4。他关掉页面。十二块的差价,在县城是两斤猪肉,在青石村是半个月的盐。在他这里,是脚本里一个try-except的容错分支。不能省,也不能乱花。他必须拿到项目奖金。实训营的A级项目,对接方有额外绩效池。李工没明说,但名单边缘的人,只能靠这个翻盘。排名是死的,项目是活的。
上午八点。实训营机房。空调外机在窗外嗡嗡作响。林尘把U盘插进公共电脑,通过内网提交架构文档。系统显示“已接收”。他坐在角落的备用机前,等回复。键盘声稀疏,几个省城重点高校的学生在讨论周末的聚餐。林尘没抬头。他盯着屏幕右下角的时间。九点十分,李工的内网消息弹出来。
“文档看了。思路对,但文件锁在并发写入时会有竞争。Linux 2.6的epoll你没用上,为什么?”
林尘手指放在键盘上。开发机的旧环境不适合直接假设epoll可用,实训营的服务器则是老旧的Red Hat Enterprise Linux 5,内核版本2.6.18。他回复:“服务器内核版本2.6.18,但开发机镜像偏旧。为保兼容,暂用poll轮询+文件锁。若允许切到服务器环境,可替换为epoll边缘触发,减少上下文切换。”
李工回得很快:“环境可以换。周三下午两点,带可运行原型。跑通两百万行,延迟压到300毫秒以内。过不了,项目换人。”
消息定格。林尘知道,这是最后通牒。他拔出U盘,起身。左脚落地时,膝盖不受控地软了一下,他迅速用右手撑住桌角。骨缝里的钝痛顺着小腿往上爬,像生锈的齿轮在强行咬合。他慢慢走回宿舍。下午需要重写核心解析模块,把poll换成更底层的逻辑,或者直接用C写扩展。他需要查Python 2.4的C API文档。图书馆三楼的计算机专区有那本《Python源码剖析》,但借阅记录显示,上周已被省理工的研究生借走。
他站在宿舍楼下,抬头看三楼的窗户。风把晾衣绳上的衬衫吹得猎猎作响。他摸出手机,给省理工的旧同学发了一条短信:“兄弟,图书馆那本《Python源码剖析》,周三前能还吗?急用。”发送成功。他靠在墙上,闭上眼。周三下午两点。还有四十八小时。脚底的痛感很清晰,像秒针在走。他睁开眼,转身往食堂走。得先吃饱。下午要写C扩展。
食堂的包子已经凉了,皮有点硬。他买了两个,就着免费汤咽下去。回到宿舍,他拉开抽屉,找出那本空白笔记本。翻到新的一页。写下:1. mmap内存映射替换文件锁;2. C扩展封装正则匹配核心;3. 2.6内核环境申请;4. 药费缺口预留。
笔尖停顿。他在第四项后面画了个圈,又在旁边补了两个字:先验证。架构图再漂亮,跑不起来也是空话。实训营的规则很明确:理论考试占30%,实操占40%,企业对接项目占30%。他前两项已经定型,能翻盘的只有最后一项。难度A的项目,历来没人敢接。接了,要么拿满分,要么直接出局。没有中间地带。
他没有再重复上午已经提交过的草图,而是把五十万行测试留下的曲线重新摊开:21.4MB,4.1秒,文件锁竞争明显;两百万行理论上能过线,但一旦换成真实磁盘、坏块和并发写入,余量会被迅速吃掉。下一步不是继续写说明,而是拿到能满负载的机器,把C扩展骨架先编出来。
下午五点四十,他向机房管理员提交B区备用机申请。理由写得很短:project_07 prototype, Python 2.4 C API, load test required。发送后,他把U盘、依赖清单和手抄的C API函数表重新检查一遍。屏幕右下角的时间跳到18:20,管理员回复:“B区3号机,临时权限到明晚八点。”
他合上笔记本,扶着床沿站起来。左脚落地时,骨缝里像有细小的砂砾在碾。他把那张待办撕下来折进口袋,转身往机房B区走。窗外的天色已经暗下去,走廊灯一盏一盏亮起。距离周三下午两点,还有四十一小时四十分钟。不能崩。
Comments
0 public responses
All visitors can read comments. Sign in to join the discussion.
Log in to comment