我是进程,一出生就被塞满了长长的任务单,上面密密麻麻的任务指令,mv,cp,while...我一个都看不懂.人类程序员告诉我,这叫shell脚本,我的任务就是跑腿,在shell街上找到能执行这些指令的人,让他们执行。这个工作听起来并不复杂,我按照人类的指示进入了贝壳街。初试身手贝壳街非常热闹,各种流程来来往往,街道两旁是大大小小的各种店铺。我左看看右看看,眼睛不够看。例如,我旁边的商店有一个巨大的招牌,上面写着[我们不生产文件,我们只是文件系统的搬运工]。这是“mv”旗舰店。街口也有这家店,招牌也非同凡响:【你负责从0到1,我来处理1到100】,原来这家店是专门负责复制备份文件的,叫cp,和它也是一家旗舰店。我从怀里拿出任务单,看看自己要做什么。我希望命令是mv或者cp,这样我就可以逛到旁边的两家旗舰店了。然而,第一个命令是“pidofxyz”。我四下看了看,怎么没看到贝壳街的pidof店呢?这时,街上的喇叭响了:进程管理4点30分下班,我需要查看进程id是否赶到0x37859ShellStreet。下班真的够早了。我小跑着来到了0x37859号。在服务窗口小姐姐的帮助下,我找到了“xyz”的进程id:8681,根据需要,记录在变量$process_id中。杀手组织的工作看似很简单。我立即检查了第二个命令。我真的不知道。当我看到它时,我感到震惊。这个命令是:kill$process_id。kill,那个$process_id不是我刚查出来的吗?8681!没想到是查询这个pid的值才杀了这个进程,也不知道他哪里做错了。没做过这种生意,杀,看名字,这是杀手组织,肯定是那种眼睛都不眨一下就把进程杀掉的,太恐怖了!这家叫kill的店真的好难找,多亏了cp旗舰店的服务员给我指路,我就来到了这家店门口。心想一定是守卫严密,门口会有大汉站岗。没想到只是一家普通的小店!有两个大灯笼迎风飘扬,上面写着:“寄”和“信”。这是杀人店吗?这就是杀手组织的所在地?我怀着忐忑的心情走进了店里。没想到小二很热情,立刻满脸笑容的迎了上来:“客官,你想做什么生意?我们这里的信件种类最齐全,你可以选择任何你想要的。”看到墙上“微笑服务”的字样,我差点怀疑自己走错片场了,把他拉到一边,小声说:“我不是来送信的,我是这次在这里杀死一个进程,你能做到吗?”我一边说着一边做了一个斩首的手势。小二看了看我的任务单,说道:“客官是第一次,这是例行公事,我们是最擅长的。不过你说的杀人流程我们不敢保证,店家只提供送信服务,送这封信,进程能不能杀掉,不是我们的责任。”“杀人不是你负责的吗?怎么和寄信这种毫无技术含量??的生意扯上关系?”小二笑道:“这是外界对我们的误解,我们不是杀手组织,我们的业务很简单,我们只负责给进程发信,而且这个信件还要通过内核转发“boss!比如你这次要kill8681,我们会发送一个叫SIGTERM的信,意思是终止进程。”小二给我解释了一下,拿出系统调用电话发了个“158681”,现在我知道了,SIGTERM对应的信号值是15,小二通过系统调用发给了内核。“杀人”的工作就这样完成了,我付了3个CPU币,带着疑惑离开了这家“传讯”店。死循环的下一条指令竟然是一个while循环,弄得我过了一会才去进程管理处查看,直到$process_id(即8681)不再执行后面的任务存在。我很清楚,这是为了确保8681进程被杀死。我一次又一次跑到制管局,累得筋疲力尽,但制管局的小姐姐每次都告诉我,8681制程活得好好的,在贝壳街的一个角落里睡得很香。出色地!“寄信”店的服务员一定是骗我的!趁着while循环,我气呼呼地回到“寄信”店,问服务员为什么收了我的钱还不干活!服务员脾气很好:“我们发信绝对不会出错,但不能保证进程会被kill掉。”我说:那你把钱退给我,我再找一个杀手。小二笑道:“客官不知道,走到哪里都一样。对于SIGTERM信号,一般kernelboss确实会杀掉对应的进程,但是如果进程已经提前打招呼,留下一个SIGTERM自己的processing函数,那么按照约定boss只会调用这个函数,函数中的进程可能在退出前做一些收尾工作,也可能根本不退出,继续开心下去。即使是进程也可以直接屏蔽掉这个信号,我估计8681进程就是这样,靠着不退出”我满脸悲凉:“那这不就相当于把名字从生死簿上勾掉了,长生不老了吗?!没有不管怎样,你必须杀了它!”闻言,小二露出旧世笑意:“客官,你听说过世间传闻吗?杀一笑,生死难测,九一(安排)布置,世间无物。“我恍然大悟,连忙问道:“九是什么意思?9号字母?”小二闻言赞许道:“看来你还是挺聪明的,一下子就打通了。9号信件就是大名鼎鼎的SIGKILL。虽然大部分信件都允许进程注册自定义信件处理函数,但是有几个特殊的字母,比如SIGKILL和SIGSEGV是不允许注册处理函数的,一旦kernelboss收到我们发来的SIGKILL信号,就相当于killwithoutpardon犹豫了。一般kill杀不死的进程可以用kill-9杀死。“原来如此!不过虽然我知道SIGKILL,但悲剧的是我只能按照任务列表执行任务,不能擅自改成kill-9$process_id!难道我真的卡住了这里?!果然生活不易,沉诚叹了口气,我无精打采准备出门,继续查看进度,估计是进度管理局的小姐姐烦死我了,每次都问同样的问题。刚要走出杀戮车间,奇怪的事情发生了,我动不了了!我好像中了定身术一样。小二跑过去一看,说:“哈哈,你好像被挂了!”我焦急地问:“说清楚,什么是hangup?”小二从柜台拿出一个邮件列表给我看:“哎,你有没有看到这个SIGTSTP,它会让进程挂掉,我们店也有这个业务。估计人类程序员发现了你好久没做下一个任务了,开始调试,一按Ctrl+Z,就发出SIGTSTP,kernelboss挂了,你们运气还不错,就是挂了,上次,一个进程做事犯了一个小错误,直接被人按Ctrl+C用SIGINT杀掉了,慢着,人很慢!我在killshop学到了很多东西,真希望人类程序员能快点学会这些知识,救我于水火之中。不过我显然高估了人类,足足过了十多秒,才看到另一个进程来到了killshop,手里的任务单上写着“kill-98681”。感谢上帝,人类找到了解决办法。过了很长一段时间,我才感觉到我的身体变轻了,我可以再次移动了。活动了筋骨之后,我赶紧跑到流程管理处查看。该查询的结果是“找不到这样的pid”。哈哈,终于可以摆脱这个问题了。循环,继续我的任务列表中的下一项。最后走之前,流程管理的小姐姐还给我讲了一个八卦。原来给我造成很大困扰的8681进程并不是故意忽略SIGTERM的。他注册了一个signal处理函数,打算打印一个log然后退出,但是在执行的时候死锁了。据说原因是打印函数不是对异步信号安全的函数,在信号处理过程中不能调用。管不了那么多,赶紧执行下一个任务,不然又要挂了……
