从一份流调报告读出中国打工人的勤劳与坚韧

太原市警方,请回应一下网友对媒体人胡新成的关心

2021年推特网黄Top10排行榜

卫生部,现在是承认失败的时候了

约炮双胞胎!王力宏男女炮友名单,首次曝光!竟有大家熟悉的“他”

分享到微信朋友圈

点击图标下载本文截图到手机
即可分享到朋友圈。如何使用?

填写问券帮助你更迅速地找到相关搜寻
查看原文

坑人的“杀手”组织

庄秋彬 码农翻身

我是一个进程,一出生就被塞了一张长长的任务单,上面是密密麻麻的任务指令,像什么 mv 了, cp 了, while 了.....   我一个都看不懂。


人类程序员告诉我这叫 shell 脚本,我的任务就是跑跑腿,到 shell 大街上找到能够执行这些指令的人,让他们去执行。


这个活儿听起来并不复杂,我按照人类的指示,进入了 shell 大街。



初试身手



shell 大街上热闹非凡,各种进程来来往往,两旁的街道是大大小小、形形色色的门店,我左看右看,眼睛都不够使了。


比如我旁边这家店,招牌巨大,上面写着 【我们不生产文件,我们只是文件系统的搬运工】,这是 “mv” 旗舰店。还有街口这家店,招牌也气势非凡:【你负责从 0 到 1,我搞定 1 到 100】,原来这家店专门负责抄录备份文件,叫做 cp ,也是旗舰店。


我从怀里掏出任务单,看看我要干的活, 我希望指令是 mv 或者 cp,这样我就可以去逛逛旁边这两家旗舰店了。


可是,第一条指令是 “pidof xyz”, 我环顾四周,怎么在 shell 大街上看不到 pidof 店铺?


这时候街上的大喇叭响了:进程管理局将于 4:30 下班,需要查询进程id的速速前往 shell 大街 0x37859 号。


下班真够早的,我一溜小跑,来到 0x37859 号,在办事窗口小姐姐的帮助下查到了 “xyz” 的进程id:8681, 按照要求,我把它记录在了变量 $process_id 中。



杀手组织



这个工作看起来很简单嘛, 我马上查看第二条指令,真是不看不知道,一看吓一跳,这条指令是:


kill $process_id


我揉揉眼睛再确认一下,没错,就是 kill , 那个 $process_id 不就是我刚刚查出来的吗?8681!没想到查询这个 pid 的值居然是为了干掉这个进程, 也不知道他做错了什么。


我还没办过这种差呢,kill,看这个名字这是个杀手组织吧,肯定都是杀进程不眨眼的那种,太可怕了!


这个叫 kill 的店可真不好找,多亏 cp 旗舰店的小二给我指了一条路,我才来到这个店铺门口, 我以为这里肯定是严密把守,门口会有彪形大汉站岗,没想到只是一个平平常常的小店!门口挂着两个随风飘扬的大灯笼,上面写着:“送” “信”。


这就是 kill 门店?杀手组织的驻地就这样?怀着忐忑的心情,我走进店中。


出乎我的意料, 小二非常热情,他马上满脸堆笑地迎上来:“客官您要办点什么业务呢,咱们这儿的信件是最全的,应有尽有,任君挑选”。


看到墙上还贴着 "微笑服务” 四个字,我差点怀疑走错片场了,我把他拉到一边,压低声音说:"我不是来送信的,我这次来是要杀一个进程,你们能办吗?"


我一边说,一边做了一个杀头的手势。


小二看了看我的任务单,说道:“客官是第一次来吧,你要办的这个是常规业务,我们最拿手了。不过你说的这个杀进程我们保证不了,小店只提供送信服务, 这封信送出去,进程能不能杀得掉就不归我们管了。”


“你们不是负责杀人吗?怎么和送信这种没技术含量的业务扯到一起了?”


小二笑道:“这是外界对我们的误解了,我们不是一个杀手组织, 我们的业务很单纯,只负责送信给进程。而且这封信还得通过内核老大转交呢!比如你这次要 kill 8681, 我们就会发送一封叫做 SIGTERM 的信,意思是终止进程。”


小二边给我解释,边掏出系统调用专用手机发送了一个 "15  8681",这下我知道了, SIGTERM 对应的信号值就是 15,小二通过系统调用发给了内核。


“杀人” 的活儿就这么办完了,我付了 3 块的 CPU 币, 满怀疑虑地离开了这个“送信”的店铺。



死循环



下一个指令竟然是个 while 循环,它让我隔一会儿就去进程管理局查询一下,直到 $process_id (也就是 8681 )不存在了才能执行后续的任务。 我心里很清楚,这是要保证那个8681的进程被杀死。


我一趟趟地往进程管理局跑,累死个人了,可是这个进程管理局的小姐姐每次都告诉我,这个 8681 号进程活得好好的,正在shell大街的某个角落呼呼大睡呢!


肯定是“送信”的那个店小二把我骗了 !趁着 while 循环的间隙,我怒气冲冲地回到了“送信”店铺,质问小二为什么收了我的钱不干活!


店小二脾气挺好:“我们送信,绝对不会出错的,但是,我们不能保证进程被杀死。”


我说到:“那你给我退钱,我去找别的杀手。”


小二哈哈笑道:“客官有所不知,你到哪里都是一样,对于 SIGTERM 信号,一般内核老大确实会干掉对应进程,但如果进程提前打过招呼,留下了一个自己的 SIGTERM 处理函数,那么按照约定老大就只会调用下这个函数。函数里面进程也许会做一些扫尾工作再退出,也许压根就不退出,继续逍遥快活。甚至进程还可以直接屏蔽掉这个信号呢。我猜 8681 号进程就是如此,赖着不退出。”


我满脸愁色:“那这样不相当于从生死簿上勾去姓名,长生不老了吗?!不管怎么样,你得把它给杀掉!"


小二闻言露出了老江湖的笑容:“客官听说过江湖传言吗?kill 一笑,生死难料,杠九一(安)排 ,世间白来。”


我若有所悟,连忙问道: "杠九是什么意思,是 9 号信件吗?"  


小二闻言露出赞许的目光:“看来你还是挺机灵的,一点就通。9 号信件那就是大名鼎鼎的 SIGKILL 了。虽然大多数信件都允许进程注册自定义信件处理函数,但有几个特别的信件,例 SIGKILL 和 SIGSEGV 是不允许注册处理函数的,一旦内核老大收到 我们送的 SIGKILL 信号,那就相当于杀无赦,斩立决,手起刀落毫不迟疑的。一般用 kill 杀不掉的进程,用上 kill -9 就可以干掉了。”


原来如此 !可是虽然知道了 SIGKILL ,但悲惨的是我只能按照任务单来执行任务,不能擅自更改为 kill -9 $process_id


天哪!难道我真的就被困在这里了吗?!



定身法



生活不易,进程叹气,我无精打采地准备出门,继续去查询进程,估计进程管理局的小姐姐都很烦我了,每次都问同一个问题。


就在我准备迈出 kill 小店时,怪事发生了,我动不了了!就像是中了定身术一样。


小二跑上前来看了看说 :“哈哈, 看来你被挂起了!”


我焦急地问:“说清楚点,什么是挂起呀?”


小二从柜台拿出了一张信件清单给我看:“喏,看到这个 SIGTSTP 没,它会让进程挂起,我们店也有这项业务的。估计是人类程序员发现你迟迟没有执行下一个任务,开始调试了。只要他们按下 Ctrl+Z,就会发出 SIGTSTP ,内核老大就把你挂起了。你小子还挺幸运的,只是被挂起,上次有个进程办事出了点小差错,直接就被人类按下了 Ctrl+C,用 SIGINT 给干掉了。慢慢等着吧,人类慢得很呐!”


在 kill 小店真是学了不少东西,真希望人类程序员也能快点学会这些知识,解救我于水火之中。


不过我显然高估了人类,足足过了十几秒,我才看到另一个进程来到了 kill 小店中,他手中的任务单赫然写着 "kill -9 8681",  谢天谢地,人类找到解决方法了。


又过了漫长的好几秒,我才感到身体一轻,又可以活动了。


舒展下筋骨,我连忙跑到进程管理局去查询,这次查询结果是 "查无此pid",哈哈,我终于可以摆脱这个循环,继续我任务单的下一条了。



尾声



离开之前,进程管理局的小姐姐还告诉了我一个小道消息,原来这个害我不浅的 8681 进程并不是故意忽略 SIGTERM 的,他注册了一个信号处理函数,打算打印一句 log 再退出,但在执行的时候竟然死锁了,据说原因是打印函数不属于异步信号安全的函数,不能在信号处理时调用。


我管不了那么多了,赶紧去执行下一个任务,要不然又要被挂起了......


后记


本文来自庄秋彬的投稿,老刘做了修改,如果你有好的文章(技术、职场、个人成长等),欢迎向码农翻身投稿,标记原创的,稿费700元





如果你也“痛恨”这样的资料和文章:一上来就是技术细节,安装步骤、配置方法,让初学者晕头转向,不知所云,看完了以后也不知道为什么有这个东西,解决了什么问题,它有什么来龙去脉, 那你一定要看一下“码农翻身”!


这里准备了50篇精华中的精华: 《用故事讲解技术,尽在码农翻身》  涉及到计算机基础知识的方方面面,可收藏可转发,enjoy!


    文章有问题?点此查看未经处理的缓存