跳到主内容
← 全部笔记

Note 01

被杀掉的进程不会释放它持有的锁。而我的发送进程,被杀是常态。

发送脚本是定时任务拉起来的瞬态进程:每半小时醒一次,干完就退。它可能在任何时刻被 taskkill、被系统重启、被我手抖 Ctrl-C 掉。

一开始的方案是在应用层加锁:进程启动时写一个锁文件,退出时删掉。逻辑很直白,问题也很直白 —— 进程被强杀时不会执行退出逻辑,锁文件留在那里,下一次定时触发看到锁就跳过。表现是发送静悄悄地停了,而且没有任何报错,因为从程序的角度看它"正常地跳过了"。

这类死锁我恢复过一次,靠的是发现当天发送量是 0。那不是监控,那是运气。

换成 SQLite 的 WAL 模式之后,并发交给数据库管:多个读不互斥,写锁由 SQLite 自己在事务边界上收放。进程怎么死,锁都跟着连接一起没了 —— 因为锁本来就不属于进程,属于连接。

真正学到的是那个判断标准:如果一个资源的释放依赖"我的代码能跑到某一行",那它在会被强杀的进程里就是不可靠的。把释放交给一个无论如何都会发生的事件(连接断开),才是可靠的。