实验三 守护进程


一、实验目的

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

二、实验原理

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

三、实验内容

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

选做部分:将编写的守护进程设置为开机自启动。

四、实验步骤

1、源程序(在目录下新建三个文件,目录可自己选择)

这里采用的目录为/home/usr/test/

1) test.c

#include<unistd.h>
 
#include<signal.h>
 
#include<stdio.h>
 
#include<stdlib.h>
 
#include<sys/param.h>
 
#include<sys/types.h>
 
#include<sys/stat.h>
 
#include<time.h>
 
void init_daemon()
 
{
 
int pid;
 
int i;
 
pid=fork();
 
if(pid < 0)
 
{
 
//创建错误,退出
 
exit(1);
 
}
 
else if(pid > 0)
 
{
 
//父进程退出
 
exit(0);
 
}
 
//使子进程成为组长
 
setsid();
 
pid=fork();
 
if(pid > 0)
 
{
 
//再次退出,使进程不是组长,这样进程就不会打开控制终端
 
exit(0);
 
}
 
else if(pid < 0)
 
{
 
exit(1);
 
}
 
//关闭进程打开的文件句柄
 
for(i=0;i<NOFILE;i++)
 
 close(i);
 
//改变目录
 
chdir("/home/usr/test");
 
//重设文件创建的掩码
 
umask(0);
 
return;
 
}
 
void main()
 
{
 
FILE *fp;
 
int i=0;
 
init_daemon();
 
while(1)
 
{
 
i++;
fp=fopen("/home/usr/test/log/trush.txt","a");
if(fp>=0)
 
{
 
 fprintf(fp,"%d\n",i);
 
 fclose(fp);
 
}
 sleep(5);
}
 
 return;
 
}

2) monitor.c

#include<unistd.h>
 
#include<signal.h>
 
#include<stdio.h>
 
#include<stdlib.h>
 
#include<sys/param.h>
 
#include<sys/types.h>
 
#include<sys/stat.h>
 
#include<time.h>
 
void init_daemon()
 
{
 
int pid;
 
int i;
 
pid=fork();
 
if(pid<0)
 
 {
 
 //创建错误,退出
 
exit(1);
 
 }
 
else if(pid>0)
 
 {
 
//父进程退出
 
 exit(0);
 
}
 
 //使子进程成为组长
 
setsid();
 
pid=fork();
 
if(pid>0)
 
 {
 
 //再次退出,使进程不是组长,这样进程就不会打开控制终端
 
exit(0);
 
 }
 
else if(pid<0)
 
 {
 
exit(1);
 
 }
 
//关闭进程打开的文件句柄
 
for(i=0;i<NOFILE;i++)
 
 close(i);
 
 //改变目录

chdir("/home/usr/test");
 
//重设文件创建的掩码
 
 umask(0);
 
return;
 
}
 
// 得到trush.txt文件大小
 
int file_size()
 
{
 
 FILE *fp=fopen("/home/usr/test/log/trush.txt","r");
 
 if(!fp) return -1;
 
 fseek(fp,0L,SEEK_END);
 
 int size=ftell(fp);
 
 fclose(fp);
 

 
 return size;
 
}
 
void main()
 
{
 
FILE *fp;
 
 time_t t;
 
init_daemon();
 
int size = file_size();
 
while(1)
 
{
 
sleep(5);
 
int size2 = file_size();
 
fp=fopen("/home/usr/test/log/monitor.log","a");
 
if(fp>=0)
 
{
 
 time(&t);
 
 fprintf(fp,"size =%d,%s\n",size, asctime(localtime(&t)));
 
fclose(fp);
 
}
 
if(size2 > size)
 
{
 
size = size2;
 
}
 
else
 
{
 
system("/home/usr/test/test");
 
}
 
}
 
 return;
 
}

3) me.sh

/home/usr/test/monitor

4) 创建文件夹(千万不要忘了,要不后面无法正常执行)

mkdir log

2、编译文件并修改文件权限

gcc -c test.c
gcc -o test test.o
gcc -c monitor.c
gcc -o monitor monitor.o
  • 将所有文件的权限修改为可读可写可操作
chmod 777 test.c test.o test monitor monitor.c monitor.o me.sh

3、设置开机自启动

1)编辑/etc/profile文件,命令如下:

sudo vim /etc/profile

2) 向文件中,添加如下内容:
添加内容

4、验证是否正确运行

1) 使用reboot命令重启计算机

2) 验证monitor是否运行,使用如下命令:

ps -ef | grep monitor

查看结果:
查看结果
3)验证test是否运行,使用如下命令:

ps -ef | grep test

查看结果:
查看结果
4)使用kill命令终止进程:
查看结果
可知,该进程已被结束。

5)monitor开机自启动,此时正在运行。等待5秒查看,test是否正确启动:
查看结果

可知,test已被monitor再次启动。

6)查看输出日志文件:

trush.txt内容:
在这里插入图片描述
monitor.log内容:
在这里插入图片描述

至此结束!!!

  • 1
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值