首页 > 技术文章 > Linux Guard Service - 守护进程再次分裂子进程

liutianchen 2018-03-03 23:51 原文

当系统区内存不能再申请新进程的时候申请会失败

在512MB内存下最多分配的子进程数

3331

[root@localhost 05]# ./test5-1 50000
expect 50000 sub process
[root@localhost 05]# 1000 sub process attributed
1000 sub process attributed
1000 sub process attributed
pid attribute failed!
Total sub process 3331 

[root@localhost 05]# pkill test5-1

在1024MB内存下最多分配的子进程数

7364

[root@localhost 05]# ./test5-1 50000
expect 50000 sub process
[root@localhost 05]# 1000 sub process attributed
1000 sub process attributed
1000 sub process attributed
1000 sub process attributed
1000 sub process attributed
1000 sub process attributed
1000 sub process attributed
pid attribute failed!
Total sub process 7364 
pkill test5-1
[root@localhost 05]# 

在1024MB内存下最多分配的子进程数

14106

[root@localhost 05]# ./test5-1 50000
expect 50000 sub process
[root@localhost 05]# 1000 sub process attributed
1000 sub process attributed
1000 sub process attributed
1000 sub process attributed
1000 sub process attributed
1000 sub process attributed
1000 sub process attributed
1000 sub process attributed
1000 sub process attributed
1000 sub process attributed
1000 sub process attributed
1000 sub process attributed
1000 sub process attributed
1000 sub process attributed
pid attribute failed!
Total sub process 14106 

由于子进程和父进程共享fork()之间的部分变量,所以在子进程中记录最大pid能够在父进程中读取。

last_pid=getpid();
......
fprintf(pfile,"mainline staying\n");

让小内存条件下的系统下分裂超量的子进程

使用排队的方法,等待旧的进程等待完毕后使用

signal(SIGCHLD,SIG_IGN);

自动释放,然后在父进程中

while(pid<0){
        sleep(1);
        printf("Waiting old process abort...\n");
        pid=fork();
}

保持等待,就能排队申请完所有进程

如果进程是系统级的,排队时可能导致-bash访问困难,例如

[root@localhost 05]# pkill test5-2

这种多线程指令可能会出现短期内无法响应的情况(提示bash fork),但是指令会被保存在终端输入队列,操作系统会“伺机”完成这条指令

使用两个变量记录释放子进程和回收子进程

如果要记录释放子进程的数量,则不能再使用信号通道函数,改用

pid_t waitpid(-1,NULL,WNOHANG);

在父进程的死循环内,反复设置这个函数用以回收僵尸进程

else{
        printf("Total sub process %d \n",att);
        printf("last pid is %d\n",pid);
        while(1){
                if(waitpid(-1,NULL,WNOHANG)>0) sub_abor++;
                printf("sub attr:%d, sub abor:%d\n",sub_attr,sub_abor);

                pfile=fopen("test5-1.log","a");
                fprintf(pfile,"mainline staying\n");
                fclose(pfile);
                sleep(1);
        }
}

在极限操作后,Linux系统还能正常工作吗?

Redhat是可以正常工作的,只是相应的队列操作的相应在内存不足的情况下所有输入队列需要排队。在内存响应来不及的情况下,-bash进程会把操作放入队列中,伺机把指令送入系统执行。送入失败则等待下一次尝试,尝试多次之后可能出现资源无法使用的情况。因此可以说操作有可能丢失。(键盘上的非ANSI按键如方向键,Backspace等将不能正常显示

推荐阅读