我们在上篇博客中提到了进程的概念,进程是运行中的程序(磁盘上的二进制文件)。今天我们来谈一下操作系统对进程的管理方式。
进程控制块(PCB):用来标识一个进程的,它包含了该进程的各个信息。它是task_struct这个结构体。
进程的控制符:全称为Process Identifier,就是标识进程唯一的身份标识,所以也成为进程标识符。
进程控制符有pid和ppid两种,pid表示进程的id,而ppid表示父进程的id。
其中每个进程都有非负的整数来表示唯一的进程ID,当一个进程终止后,其进程的ID就又可以被其他进程进行使用。
进程的创建:
在Linux中创建进程用fork()函数:
fork()函数
头文件 #include
函数原型:pid_t fork(void);
作用:一个现有的进程调用fork函数可以创建一个子进程
调用一次将返回两次:子进程成功返回0,出错会返回-1,父进程返回子进程的PID,
说明:子进程是父进程的副本。
注意:父进程不共享存储空间的部分,但是共享正文段
这里用到了写实拷贝,当父进程或者子进程进行修改的时候,内核只为要修改的区域的地方的内存制作一个副本。
父进程和子进程的一些区别:
1、fork()的返回值的不同,子进程返回0;父进程返回子进程的PID
2、进程的ID不同,其各自的父进程的ID不同
3、子进程的tms_utime,tms_stime,tms_cutime和tms_ustime均被设置为0
4、父进程的文件锁,不会被子进程继承
5、子进程的未处理闹钟会被清理
6、子进程的未处理信号集被设置为空值
7、父进程和子进程有独立的地址空间和PID参数
一个进程使用fork创建子进程,如果子进程退出,而父进程并没有调用wait或waitpid获取子进程的退出状态信息,那么子进程的进程描述符仍然保存在系统中。这种进程称之为僵死进程。
危害:如果进程不调用wait / waitpid的话, 那么保留的那段信息就不会释放,其进程号就会一直被占用,但是系统所能使用的进程号是有限的,如果大量的产生僵死进程,将因为没有可用的进程号而导致系统不能产生新的进程. 此即为僵尸进程的危害,应当避免。
解决办法:
1)通过信号机制
子进程退出时向父进程发送SIGCHILD信号,父进程处理SIGCHILD信号。在信号处理函数中调用wait进行处理僵尸进程。
2)fork两次
《Unix 环境高级编程》8.6节说的非常详细。原理是将子进程变成为孤儿进程,从而其的父进程变为init进程,通过init进程可以处理僵尸进程。
一个父进程退出,而它的一个或多个子进程还在运行,那么那些子进程将成为孤儿进程。孤儿进程将被init进程(进程号为1)所收养,并由init进程对它们完成状态收集工作。
以上就是我操作系统对进程的管理、僵尸进程、僵尸进程的处理方法和危害以及孤儿进程的讨论,望各位同仁进行指正!!!