早上刚到工作岗位上,旁边的博士小姐姐就向我请教问题,是关于多进程的问题。
她用python写了一个多进程的程序,读取两万个文件做分析,然后写到两万个结果文件里。我大概了解了一下情况,并没仔细看代码,带着身上由于爬了12层楼还冒着热气的身体,我就奔过去立在了显示器前。
现在的问题是,她这个程序运行了一段时间后,就全部休眠了,然后她看结果也只跑了一半,所以她想知道程序怎么才可以继续运行。
我通过ps查看了一下,果然50多个进程全是休眠状态。我一开始也不知道为何这些进程会休眠,能想到的最直接原因是程序里使用了sleep函数,不过我仔细读了一下代码,发现就是调用了pandas读取和写入文件,没做任何多余操作。
一下子陷入了尴尬。我又仔细看了下python的进程,发现居然有一百多个僵尸进程,分别是前天和昨天的。她告诉我,同样的代码,之前都可以运行,今天突然就不行了。我当时并不太清楚僵尸进程产生的原因,所以无法解释。
只能去看启动脚本,我发现她只用了nohup,所以想加个&放在后台运行,结果改完脚本之后一保存,居然报错了。小姐姐立马反应过来,说这是硬盘空间不够了。
我立马反应过来,告诉她,我知道你的程序为什么会休眠了!就是因为没有硬盘空间了,导致写文件的IO阻塞了,所以进程休眠了。
我如释重负,迅速撤下战场,开始反思。这么简单的问题,我居然只能偶然发现,花了半个小时无谓的排查。我迅速Google的一下僵尸进程产生的原因,发现是由于子进程已经结束,但是父进程并未读取其结束状态,导致其虽然不占用资源,但是还占用着进程标识符位置,没有人来为其收尸。看起来是程序问题,所以我套在今天这个场景里,因为这是用的python的multi processing模块,和原生c语言差远了,但是也可以知道其子进程的exit状态确实不被父进程所接收,而由于某种原因,父进程一直没退出,所以僵尸了。
还有一个问题就是,有哪些情况会让进程限入休眠状态?
至少,在没有使用CPU时一般都是处于休眠,比如IO的等待之类的被动让出CPU,和程序主动让出CPU。
另外就是,以为自己很清楚的概念,在给别人解释时,却突然哑语了。小姐姐突然问: 进程和线程有什么区别?你怎么用最简洁的语言解释清楚呢?