一。僵尸进程
用ps命令观察进程的执行状态时,经常看到某些进程的状态栏为defunct,这就是所谓的“僵尸”进程。“僵尸”进程是一个早已死亡的进程,但在进程表(processs table)中仍占了一个位置(slot)。由于进程表的容量是有限的,所以,defunct进程不仅占用系统的内存资源,影响系统的性能,而且如果其数目太多,还会导致系统瘫痪。每个Unix进程在进程表里都有一个进入点(entry),核心程序执行该进程时使用到的一切信息都存储在进入点。当用ps命令察看系统中的进程信息时,看到的就是进程表中的相关数据。当以fork()系统调用建立一个新的进程后,核心进程就会在进程表中给这个新进程分配一个进入点,然后将相关信息存储在该进入点所对应的进程表内。这些信息中有一项是其父进程的识别码。当这个进程走完了自己的生命周期后,它会执行exit()系统调用,此时原来进程表中的数据会被该进程的退出码(exit code)、执行时所用的CPU时间等数据所取代,这些数据会一直保留到系统将它传递给它的父进程为止。由此可见,defunct进程的出现时间是在子进程终止后,但是父进程尚未读取这些数据之前。如果该进程的父进程已经先结束了,那么该进程就不会变成僵尸进程。因为每个进程结束的时候,系统都会扫描当前系统中所运行的所有进程,看看有没有哪个进程是刚刚结束的这个进程的子进程,如果是的话,就由Init进程来接管他,成为他的父进程,从而保证每个进程都会有一个父进程。而Init进程会自动wait其子进程,因此被Init接管的所有进程都不会变成僵尸进程。
但是系统的进程表容量是有限的,所能使用的进程号也是有限的,如果大量的产生僵尸进程,将因为没有可用的进程号而导致系统不能产生新的进程。
由于调度程序无法选中Defunct 进程,所以不能用kill命令删除Defunct 进程,惟一的方法只有重启系统
因为defunct进程是已经停止的,所以使用杀死进程的方法来杀defunct进程是无效的。defunct进程不使用CPU或硬盘等系统资源,而只使用极少量的内存用于存储退出状态和资源使用信息。
一个进程在调用exit命令结束自己的生命的时候,其实它并没有真正的被销毁,而是留下一个称为僵尸进程(Zombie)的数据结构(系统调用exit,它的作用是使进程退出,但也仅仅限于将一个正常的进程变成一个僵尸进程,并不能将其完全销毁)
二。避免僵尸进程的方法:
父进程创建一个子进程,该父进程等待子进程的结束。子进程在去创建孙子进程。孙子进程的父进程直接退出,孙子进程的子进程进行相关的函数处理。即:父 子 孙 。子进程直接退出,导致父进程也跟着退出,孙子进程成为孤儿进程,被init进程接收成为孤儿进程,避免了僵尸进程的产生。
三。php是进程安全的,但是线程不安全的
四:socket_getpeername ($client,$clientip,$clientport);可以获得远端的客户端的IP地址和端口号。
避免僵尸进程的方法:
父进程创建一个子进程,该父进程等待子进程的结束。子进程在去创建孙子进程。孙子进程的父进程直接退出,孙子进程的子进程进行相关的函数处理。即:父 子 孙 。子进程直接退出,导致父进程也跟着退出,孙子进程成为孤儿进程,被init进程接收成为孤儿进程,避免了僵尸进程的产生。
总结:创建TCP服务器端的步骤:
1.socket_create()
2.socket_bind()
3.socket_listen()
4.socket_accept()
5.pcntl_fork()
父:pcntl_wait($pid);
子:pcntl_fork()
父:exit();
子:进行相关处理==》socket_read()/socket_write()
对于进程间的继承问题:子进程可以继承父进程的许多内容,但是像$db这样的对象不能继承。
阅读(952) | 评论(0) | 转发(0) |