实验三 守护进程

实验三 守护进程

一、实验目的

1、了解守护进程的生命周期及应用。
2、掌握编写守护进程的五个基本步骤。

二、实验原理

1、守护进程是运行在后台的一种特殊进程,用于周期性地执行某种任务或等待处理某些发生的事件。
2、守护进程生存期较长,常常在系统引导装入时启动,在系统关闭时终止。守护进程的名称通常以d结尾。
3、编写守护进程的五个步骤:
(1)fork()创建子进程,exit()退出父进程。
(2)setsid()在子进程中创建新会话,使子进程脱离原来的控制。
(3)chdir()改变当前的工作目录为根目录,防止可卸载的文件系统被占用。
(4)umask()设置文件权限掩码,防止继承来的文件创建屏蔽字,拒绝某些权限。
(5)close()关闭文件描述符,由于子进程从父进程继承一些打开的无用的文件,
需要将其关闭,防止占用资源

三、实验内容

1、编写守护进程test.c,test每5秒钟打印一个数字,定向输出到trush.txt。
2、编写并编译monitor.c,其功能为每5秒检测一次test是否正在运行;若未运行,则运行该程序。
3、先验证test是否能正常运行,需要执行test,然后查看数字是否正常输出至trush.txt。
4、执行kill命令终止进程,使用命令查看test此时并未运行。
5、执行monitor,5秒钟后使用命令查看test此时已经运行。
选做部分:将编写的守护进程设置为开机自启动。

四、实验过程

实验代码:

Test.c:
#include<unistd.h>
#include <signal.h>
#include<signal.h>
#include<stdio.h>
#include<stdlib.h>
#include<sys/param.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<syslog.h>
#include <fcntl.h>
int main(int argc, char *const *argv){
int  pc;
int k=0;
FILE *fp;
pc=fork();//创建子进程
  if(pc<0)
    {
        printf("fork error\n");
        exit(1);
    }
    else if(pc>0)
    {
        exit(0);//第二步,父进程退出
    }
    else
    {
        setsid();//第三步,创建新会话
        chdir("/");//第四步,将当前目录改为根目录
        umask(0);//第五步,重新设置文件权限掩码
       for (int i = 0; i < getdtablesize(); ++i) {
            close(i);}//第六步,关闭文件描述符
while(1){
      k++;
    sleep(5);
fp=fopen("/home/mj/sy3/trush.txt","a");
if(fp>=0){
 fprintf(fp,"%d\n",k);
fclose(fp);
}

}

}
return 0;
}
Monitor.c:
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
int main() 
{	 
  pid_t pid = 0;
	pid = fork();
	if(pid<0){
		exit(-1);
	}
	if(pid>0){
		exit(0);
	}
	pid = setsid();
	if(pid<0){
		exit(-1);
	}
	chdir("/");
	umask(0);
	int i=0;
	for(i=0;i<getdtablesize();i++){
		close(i);
	}
   int num=0;
   while(1){
	char buff[128]={0};
	FILE *fp1 =NULL;

	fp1 = popen("ps -ef | grep '/test'","r");     //执行ps -ef | grep '/test’这个命令
	fread(buff,1,127,fp1);   //将这个命令里的内容输出到buff数组中
	pclose(fp1);
        const char pattern[] = "/home/mj/test";
    	char *p = strstr(buff, pattern);  //  字符串比较函数  看buff数组里是否有守护进程的路径
    	
    	if(NULL ==p){   //若守护进程未启动
        	FILE *fp2 = NULL;
			fp2 = popen("~/test","r");//使用popen()函数启动
			pclose(fp2);		
    	}
 		sleep(5);	//每隔五秒检测一次
   }	    
   return 0;   
};

实验截图:

在这里插入图片描述
在这里插入图片描述
选做部分:将编写的守护进程设置为开机自启动
①编写mot.sh文件,写入守护进程test的路径
在这里插入图片描述

②/etc/profile文件为系统的每个用户设置环境变量信息,所以将mot.sh文件所在的路径写入/etc/profile,这样test就能开机自启动了
在这里插入图片描述

③重新启动,输入ps -ef命令,可以看到/home/mj/test已经启动了
在这里插入图片描述

六、实验总结

守护进程是一种长期运行的进程,在后台运行,它是独立于控制终端的,使一个进程成为守护进程的步骤为:1)fork()创建子进程,父进程exit()退出;2)在子进程调用setsid()创建新会话,释放与控制终端之间的关联关系;3)在子进程中调用chdir()让根目录“/”成为子进程的工作目录,这里在上课时不太理解,在做实验时查阅资料才明白假如在/tmp/dada目录下创建一个守护进程,守护进程运行之后,这个目录可能没有任何用处了,你需要卸载它,但是守护进程在这个目录下运行,你便不能卸载4)在子进程中调用umask()重设文件权限掩码为0,以确保进程创建一个文件或者目录时候拥有所需权限;5)在子进程中close()不需要的文件描述符;
monitor.c监视test的原理为,先使用popen函数来执行ps命令,并把结果输出到一个数组中,然后看test的路径名是否在这个数组中,如果没有的话,说明test并未启动,此时就再次调用popen函数启动test。在实验时注意,如果同时运行多次test,那么他们都会往trush.txt文件中写入内容

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值