说起僵尸首先想到的林正英拍的那些僵尸鬼片,那些吸血、懂一些妖术、到处祸害人的可怕的东西。我的印象中有一种僵尸的说法就是:那些生前遭受到坏人的迫害,死后由于各种怨气、意念没有散去,最终没有到阎王那边报到的死人吧。
下面是一段从百度百科上面找到的一些有关僵尸的解释:
《阅微草堂笔记》把尸体成为僵尸的原因分成两项:新尸突变及葬久不腐。
养尸地
,这较为科学。土壤土质酸碱度极不平衡,不适合有机物生长,因此不会滋生蚁虫细菌,尸体埋入即使过百年,肌肉毛发也不会腐坏,有些资料显示尸体的毛发,指甲会继续生长(其实是皮肤脱水后毛发和指甲根部外露造成的错觉)。风水学中亦有此一说。
(小时候听老人讲过:生于
红沙
日,死于黑沙日葬于飞沙地者就会成僵尸,“飞沙地” 即“土壤土质酸碱度极不平衡,不适合有机物生长之地”)
坊间流传道家有太阴炼形之法,尸体葬数百年,期满便会复生,新死的尸体被邪物/邪气附身,尸体吸收了阳气,借人生气而
尸变
,人死之际,魂一散而魄滞。
袁枚《子不语》:人之魂善而魄恶,人之魂灵而魄愚,魄主宰人身,当魂离开人体,便会沦为恶鬼僵尸。
上面的这段话给我们三个知识:
(1)僵尸就是人死后尸体由于土壤原因,没有腐烂。这个类似于木乃伊吧;
(2)利用道家的一种法术可以让尸体埋葬超过百年后复活,复活后借助于新死的尸体存活;
(3)《子不语》中的解释是人是由魂和魄两部分组成的。魂是人的聪明、善良的一面,魄是人的邪恶、愚笨的一面,魂主宰这人身,当魂离开人体以后就只剩下魄了,变成了恶鬼。
好了有关僵尸的讨论就到这里吧,之所以讨论僵尸是因为和我今天理解的linux中的“僵尸进程有关系”
所谓的僵尸进程:父进程fork一个子进程a,a运行结束后会释放大部分资源,如释放内核栈,递减文件描述符,文件系统的引用数,释放mm_struct结构等,但是会保留文件描述符,进程表中代表子进程表项的资源,虽然子进程不在运行,但是可以查到他的相关信息。
直到父进程正常终止,或者父进程调用wait时子进程才彻底释放资源。
呵呵,早上开始下雪了,瑞雪兆丰年。晚上还有年会……
接着上次的僵尸进程继续说吧:
正常的情况应该是子进程执行完毕后,在父进程未执行wait()函数或者未执行完毕之前。这段时间子进程是出于僵尸状态的。
等父进程执行完毕或者调用wait完毕,子进程将彻底的释放资源,消逝。
下面是个测试程序: 正规的情况,父进程调用wait去等待子进程运行玩。在子进程未运行完毕之前,父进程调用wait一直出于阻塞状态。一旦子进程运行完毕,那么父进程立即执行wait。所以子进程几乎没有僵尸状态。呵呵……
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
int main(void)
{
pid_t pid_a;
pid_a = fork();
int i = 0;
if(pid_a == 0)
{
while(i < 30)
{
printf("this is a children program\n");
i++;
sleep(1);
}
return 0;
}
else
{
printf("this is a father program\n");
wait(NULL);
return 0;
}
}
运行结果如下图:
子进程进入僵尸状态的原因是,子进程运行完毕后会留一些信息,告诉父进程自己是正常退出,还是非正常退出。但是父进程在子进程之前死了话,那么父进程在退出时内核中do_exit()会调用exit_notify()为子进程在当前的线程组中重新找一个父进程。如果找不到它的父进程就是init了,init会例行wait去处理僵尸进程。
把上面代码中的if(pid_a == 0)中pid_a ==0 改为pid_a !=0,注释掉wait(NULL)就会出现子进程的僵尸状态。如下图:
为了让父进程尽早的处理子进程的僵尸状态。当子进程推出前为父进程发送一个信号,那么父进程用wait回收就好了。这个是编程应该注意的。
不过我发现父进程先结束时,如果子进程的新父亲是init的话,init回收僵尸进程的速度是相当快得。呵呵,可见init 这个进程真是“僵尸的天敌”!(这块可以自己写个程序验证一下,记住别人说的不一定对)
编程中好的父进程应该是不做很多事情,专门用wait蹲点,一旦发现子进程变成“僵尸”就把他回收了,也就是说让父进程编程一个专业的僵尸杀手,要是父进程先于子进程之前死掉了,那么父进程就很遗憾扮演不了“僵尸杀手”的角色了。
说了这么多,目的就是让父进程扮演一个高效的“僵尸杀手”,不要让系统中出现太多的僵尸,那么社会也就和谐了。僵尸也不像人们传说中的那么可怕吧,对它越了解,你会发现它也很可爱。呵呵……