程序说明文档
目录
2.2章任务描述
本章节的程序是用于探讨僵尸进程可能出现的各种危害,本人总结了僵尸进程主要产生的三种危害:浪费资源、占用端口、导致父进程死锁。
算法1:僵尸进程浪费资源
输入:无
输出:子进程打印出pid以及父进程的pid
错误处理:若fork()函数返回值小于0,抛出fork()错误信息,malloc抛出内存不足信息
UML图:
代码:
/*
* @Author: DC
* @Date: 2021-07-28 15:34:00
* @LastEditTime: 2021-07-29 14:48:54
* @LastEditors: DC
* @Description:
* @FilePath: /c1/5.c
* Never lose my passion
* 本程序用于探讨僵尸进程占用资源的情况
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
int main()
{
pid_t pid;
//循环创建子进程
while (1)
{
pid = fork(); //创建子进程
int pronun = 1000000;
double *str = (double *)malloc(pronun * 100000); //分配内存
getchar();
if (pid < 0)
{
system("free -m"); //打印系统资源占用
perror("fork error:");
exit(1);
}
else if (pid == 0)
{
printf("I am a child process.\nI am exiting.\n");
//子进程退出,成为僵尸进程
exit(0);
}
pronun++;
}
return 0;
}
算法2:僵尸进程占用端口
输出:子进程打印出pid以及父进程的pid
错误处理:若fork()函数返回值小于0,抛出fork()错误信息,JNI抛出虚拟机错误
算法3:僵尸进程导致父进程死锁
输入:无
输出:子进程打印出pid以及父进程的pid
错误处理:若fork()函数返回值小于0,抛出fork()错误信息,查询目录为空错误
UML图:
代码:
/*
* @Author: DC
* @Date: 2021-07-28 15:34:00
* @LastEditTime: 2021-07-29 14:52:49
* @LastEditors: DC
* @Description:
* @FilePath: /c1/6.c
* Never lose my passion
* 本程序用于探讨僵尸进程导致父进程死锁
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <dirent.h>
#include <string.h>
#include <ctype.h>
int Get_System_Process_Number() //通过遍历/proc文件夹下文件夹数目查询系统当前进程数量
{
DIR *dp; //文件浮标
struct dirent *dirp;
int i, len, count = 0;
if ((dp = opendir("/proc")) == NULL) //文件目录为空错误处理
{
fprintf(stderr, "%s file %d line %s", __FILE__, __LINE__, strerror(errno));
exit(1);
}
while ((dirp = readdir(dp)) != NULL) //遍历进程数目
{
if (dirp->d_type == DT_DIR)
{
len = strlen(dirp->d_name);
for (i = 0; dirp->d_name[i] != 0; ++i)
{
if (!isdigit(dirp->d_name[i]))
{
break;
}
}
if (len == i)
{
// printf("d_name: %s\n", dirp->d_name);
++count;
}
}
}
closedir(dp); //关闭资源
return count; //返回数值
}
int main()
{
pid_t pid;
//循环创建子进程
while (1)
{
pid = fork();
if (pid < 0)
{
printf("当前系统运行进程数 %d\n", Get_System_Process_Number());
perror("fork error:");
exit(1);
}
else if (pid == 0)
{
// printf("I am a child process.\nI am exiting.\n");
//子进程退出,成为僵尸进程
exit(0);
}
}
return 0;
}
2.3章任务描述
本章节的程序是用于探讨不同僵尸进程的解决方法,本人总结了解决僵尸进程的四种方法,分别是:父进程调用wait()函数,父进程调用waitpid()函数,在信号处理函数中解决僵尸进程,定期重启父进程。
算法1:wait()函数处理僵尸进程
输入:无
输出:子进程打印出pid以及父进程的pid
错误处理:若fork()函数返回值小于0,抛出fork()错误信息
UML图:
代码:
/*
* @Author: DC
* @Date: 2021-07-28 15:44:40
* @LastEditTime: 2021-07-28 18:00:14
* @LastEditors: DC
* @Description:
* @FilePath: /c2/1.c
* Never lose my passion
* 本程序用于探讨父进程使用wiat()函数方法处理子进程,从而防止僵尸进程的出现。
*/
#include <stdio.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <wait.h>
#include <errno.h>
int main(int argc, char *argv[])
{
while (1) //主循环
{
pid_t pid = fork(); //产生一个子进程,pid用于记录fork()返回值
int status = -1; //用于记录子进程退出信息
if (pid < 0)
{
perror("fork error:"); //抛出错误
}
else if (pid == 0)
{
printf("this is child , pid = %d , ppid = %d\n", getpid(), getppid()); //打印子进程信息
exit(1);
}
wait(&status);
sleep(1);
}
return 0;
}
算法2:waitpid()函数处理僵尸进程
输入:无
输出:子进程打印出pid以及父进程的pid,父进程打印未阻塞标识
错误处理:若fork()函数返回值小于0,抛出fork()错误信息
UML图:
代码:
/*
* @Author: DC
* @Date: 2021-07-28 16:55:14
* @LastEditTime: 2021-07-29 09:09:05
* @LastEditors: DC
* @Description:
* @FilePath: /c2/2.c
* Never lose my passion
* 本程序用于探讨父进程使用wiatpid()函数方法处理子进程,从而防止僵尸进程的出现。
*/
#include <stdio.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <wait.h>
#include <errno.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
while (1) //主循环
{
pid_t pid = fork();
int status = -1;
printf("未阻塞\n"); //父进程的未阻塞的标识
if (pid < 0)
{
perror("fork error:");
}
else if (pid == 0)
{
printf("this is child , pid = %d , ppid = %d\n", getpid(), getppid()); //打印子进程信息
exit(1);
}
else
{
waitpid(pid, NULL, 0); //给waitpid()函数传入fork()函数的返回值。waitpid函数就会等待该进程的退出信号
}
// sleep(1);
}
system("pause");
return 0;
}
算法3:信号处理函数处理僵尸进程
输入:无
输出:子进程打印出pid以及父进程的pid,父进程打印未阻塞标识
错误处理:若fork()函数返回值小于0,抛出fork()错误信息
UML图:
代码:
/*
* @Author: DC
* @Date: 2021-07-28 17:22:50
* @LastEditTime: 2021-07-29 09:11:59
* @LastEditors: DC
* @Description:
* @FilePath: /c2/3.c
* Never lose my passion
* 本程序用于探讨父进程调用信号处理函数方法处理子进程,从而防止僵尸进程的出现。
*/
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <wait.h>
#include <errno.h>
void Listen(int signal) //信号处理函数,系统给该函数传入子进程的pid
{
int status;
while (waitpid(-1, &status, WNOHANG) > 0)
;
}
int main(int argc, char *argv[])
{
signal(SIGCHLD, Listen); //启动信号侦听
while (1)
{
pid_t pid = fork();
int status = -1;
printf("未阻塞\n"); //父进程未阻塞的标识
if (pid < 0)
{
perror("fork error:");
}
else if (pid == 0)
{
printf("this is child , pid = %d , ppid = %d\n", getpid(), getppid()); //打印子进程信息
exit(1);
}
}
return 0;
}