1、孤儿进程(子进程没有结束,父进程结束了,子进程就成了孤儿,被init进程收养)
2、僵尸进程(进程结束后,操作系统会保留其退出状态,进程号等信息,并放回给其父进程。父进程通过调用wait函数获取或忽略这些信息,并销毁这些信息,如果父进程不处理,就长生了僵尸进程,直到被init收养释放)
根本原因:子进程死了,父进程不管不问。
程序已经结束,但相关数据任驻留在内存(pid被占却没有使用,资源浪费)。
避免僵尸进程:
wait或waitpid : 会导致父进程阻塞
进程死后会自动给父进程发SIGCHLD信号,父进程对这个信号进行处理,或直接忽略。
3、 守护进程:脱离终端在后台独立运行(后缀为d)
创建守护进程的步骤:
1. 创建子进程,父进程结束,所有任务在子进程中进行。:摆脱父亲的控制
2. 设置新的回话(setsid): 摆脱终端的控制
3. 设置当前目录为根目录(chdir) :摆脱的更彻底,不要终端的东西(设置)
4. 重设文件权限掩码(umask):自行设置
5. 关闭不需要的文件描述符号 :重新开始
无法调用标准输入,标准输出等 :无法享用有父母的福利
只能通过文件操作
僵尸进程及处理方法:
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <signal.h>
void hander(int sig)//法一:自定义处理函数
{
;
}
int main()
{
signal(SIGCHLD,SIG_IGN);//法二:忽略
int i;
pid_t pid;
for(i=0;i<100;i++)
{
pid=fork();
if(pid<0)
{
printf("fork()");
exit(0);
}
if(pid==0)
break;
}
if(pid==0)
exit(0);
// signal(SIGCHLD,SIG_IGN);放在这里僵尸还会出现
// signal(SIGCHLD,hander);
sleep(60);
return 0;
}
守护进程代码
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
int main()
{
pid_t pid;
pid=fork();
if(pid <0)
{
perror("fork");
exit(-1);
}
if(pid>0)
exit(0);
setsid();
chdir("/");
umask(0);
int i;
for(i=0;i<65535;i++)
close(i);
sleep(10);
//重生,该干嘛干嘛
/* while(1)
{
}
*/
return 0;
}