戏班子的收场锣
走马戏班
走马戏班是方圆百里最有名的班子,班主姓罗,人称罗老板。戏班每到一处,搭台、唱戏、拆台、走人,有条不紊。
罗老板有一条铁规矩:收场的顺序,一步不能乱。
每场戏结束,流程是这样的:
第一,打收场锣。三声锣响,告诉所有人——戏要散了。
第二,演员退场。台上的角儿们依次走下台,回到后台卸妆。
第三,拆台。布景拆掉,道具装箱,灯绳卷好。
第四,撤棚。戏棚拆解,装车,马匹牵出来,上路。
罗老板说:"这个顺序,是我师父的师父传下来的。谁改,谁倒霉。"
罗老板病倒了
那年秋天,戏班到了柳河镇。第一场《长坂坡》爆满,镇上的人挤满了棚子。
可第二天,罗老板受了风寒,高烧不退。他把副手阿顺叫到床前:"阿顺,今晚的《空城计》,你来主持收场。记住——"
罗老板咳了两声,把收场顺序说了一遍。
阿顺点头:"记住了,记住了。"
阿顺的主意
阿顺是个聪明人。聪明人都喜欢想——能不能更快一点?
晚上《空城计》落幕,阿顺站在台侧,心里盘算:
"打锣——半盏茶。等演员退场——一盏茶。拆台——两盏茶。撤棚——三盏茶。加起来七盏茶的功夫。如果我把顺序调一调呢?"
阿顺的"优化方案"是这样的:
第一步,先撤棚。棚子拆了,回头拆台的时候宽敞。
第二步,拆台。道具装箱,布景卸下来。
第三步,打锣。通知演员——收工了。
第四步,演员退场。但台已经拆了,灯已经卷了,演员摸着黑下台。
阿顺觉得这个顺序"更合理"。于是他开始干。
灾难
阿顺喊来棚工:"撤棚!"
棚工愣住了:"阿顺哥,戏还没散呢。诸葛亮还在城楼上弹琴。"
阿顺说:"没事,先拆外围。不影响。"
棚工们拆了棚布,收了棚绳。台上的诸葛亮弹着琴,头顶的棚子已经没了。
接着阿顺喊:"拆台!"
道具师傅急了:"台上司马懿的兵马还在布景后面候场呢!"
阿顺说:"让他们从侧面绕。"
道具师傅们开始搬布景。城墙刚拆了一半,司马懿带着兵从侧面冲出来了——可城楼已经没了。司马懿站在空荡荡的台上,对着空气演完了"撤兵"那段。
然后是第三步——阿顺想起来,还没打锣。
他拎起铜锣,咣咣咣敲了三下。
台上的诸葛亮正唱着"我正在城楼观山景",锣声一响,他愣住了——戏还没唱完呢,收场锣怎么响了?
后台的琴师还在拉胡琴,突然灯灭了,因为拆台的已经把灯绳收了。
司马懿的兵马从后台绕出来,踩在散落一地的道具上,绊倒了三个。
罗老板在病床上听到动静,挣扎着爬起来,拄着拐杖走到戏棚——看到的是一个拆了一半的台、一群不知所措的演员、和一地狼藉的道具。
罗老板深吸一口气:"阿顺——你把顺序反了。"
为什么顺序不能乱
罗老板把所有人召集起来,坐在拆了一半的台上,说了一段话:
"收场锣必须先打。为什么?因为锣不打,演员不知道要停。 你要拆台,演员还在唱——他踩在正在拆的台板上,摔了算谁的?"
"演员必须先退场。为什么?因为他们在台上,道具就不能收。 人没走,你把椅子撤了,他一屁股坐空,谁负责?"
"拆台必须在撤棚之前。为什么?因为棚子是挡风遮雨的。 你先把棚子拆了,万一突然下雨,道具全淋坏。"
"最后才撤棚。为什么?因为棚子是最外层的壳,所有的东西都在棚子里。 棚子一撤,意味着一切结束。棚子撤了,就不能再有人进出,不能再有东西搬动。"
罗老板看着阿顺:"你觉得自己聪明?把顺序倒过来——先拆壳,再搬东西,再赶人——人还没走,壳就没了。这是什么?这叫拆自己人的台。"
阿顺低着头。
"你记住。"罗老板说,"搭台的时候,从外往里搭。拆台的时候,从里往外拆。 这是最简单、也最重要的道理。你把这个顺序弄反了,不是快慢的问题,是会不会塌的问题。"
代码里的收场锣
罗老板的收场顺序,翻译成程序员的话就是:
- 收场锣 =
exitFlag = true; cv.notify_all();。告诉所有线程——该停了。 - 演员退场 =
worker.join()。等所有线程安全退出,排空手头的工作。 - 拆台 = 停止依赖的内部服务。Logger 停了,LogPublisher 停了。
- 撤棚 = 停止最外层的传输层。MqttClient 最后停。
阿顺的"优化"——先撤棚,再拆台,最后赶人——翻译成代码,就是那个导致 112 个 Valgrind 错误的原始 stop():
1 | void SystemFactory::stop() |
棚都拆了,人还在台上唱。这就是 use-after-free。
后记
罗老板病好之后,把收场顺序写成了戏班的班规,刻在一块木板上,挂在后台:
1 | 一、锣响三声,告知散场 |
后来有人问罗老板:"您这收场四步,跟写代码的 stop() 顺序一模一样。您学过编程?"
罗老板说:"我不懂什么编程。但我知道——往外走的时候,先进来的后出去。 你进戏棚,先过棚门,再过台口,最后上台。你出去的时候,得先下台,再过台口,最后出棚门。反着来,就会撞到墙上。"
栈,后进先出。依赖链,最上层先停。罗老板没学过数据结构,但戏班子的收场锣已经敲了三百年。

