目录
3、 首先验证print是否能正常运行,需要执行print,然后查看系统时间是否正常输出至trush.txt。
4、执行kill命令终止进程,再查看进程列表,发现print此时并未运行。
5、执行mymonitor,等待并查看进程列表,print此时已经继续运行。
一、实验目的
1、了解守护进程的生命周期及应用。
2、掌握编写守护进程的五个基本步骤。
二、实验内容
1、编写print.c,程序实现每隔5秒钟打印当前系统时间,定向输出到文件trush.txt。
2、编写守护进程mymonitor.c,其功能为每6秒检测一次print是否正在运行;若未运行,则启动运行该程序。
3、 首先验证print是否能正常运行,需要执行print,然后查看系统时间是否正常输出至trush.txt。
4、执行kill命令终止进程,再查看进程列表,发现print此时并未运行。
5、执行mymonitor,等待并查看进程列表,print此时已经继续运行。
6、将编写的守护进程设置为开机自启动。
选做部分:
由于守护进程脱离控制终端,无法像其他程序一样通过输出错误信息到控制终端来通知用户,因此需要使用日志管理服务,将出错信息保存至日志文件中。
Linux C中提供的系统日志写入接口包括三个函数:openlog,syslog和closelog。此处要求将守护进程的调试(debug)日志记录写入到指定好的日志文件/tmp/mydebug中。
三、实验具体分工
组内人员独立完成实验
四、实验步骤、源程序及结果截图
1、编写print.c
程序实现每隔5秒钟打印当前系统时间,定向输出到文件trush.txt。
源程序:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <time.h>
int main() {
// 创建子进程
pid_t pid = fork();
// 如果建子进程失败,则退出程序
if (pid < 0) {
fprintf(stderr, "无法创建子进程\n");
exit(1);
}
// 如果是父进程,则退出程序
if (pid > 0) {
exit(0);
}
// 创建新会话,并成为会话首进程和组长进程
if (setsid() < 0) {
fprintf(stderr, "无法创建新会话\n");
exit(1);
}
// 关闭标准输入、标准输出和标准错误输出
close(STDIN_FILENO);
close(STDOUT_FILENO);
close(STDERR_FILENO);
// 打开文件trush.txt,用于定向输出
FILE* file = fopen("trush.txt", "w");
if (file == NULL) {
fprintf(stderr, "无法打开文件trush.txt\n");
exit(1);
}
// 守护进程主循环
while (1) {
// 获取当前系统时间
time_t now = time(NULL);
struct tm* tm_info = localtime(&now);
char buffer[26];
strftime(buffer, sizeof(buffer), "%Y-%m-%d %H:%M:%S", tm_info);
// 将当前系统时间输出到文件trush.txt
fprintf(file, "%s\n", buffer);
fflush(file);
// 等待5秒钟
sleep(5);
}
// 关闭文件
fclose(file);
return 0;
}
运行结果截图:
2、编写守护进程mymonitor.c
其功能为每6秒检测一次print是否正在运行;若未运行,则启动运行该程序。
3、 首先验证print是否能正常运行,需要执行print,然后查看系统时间是否正常输出至trush.txt。
源程序:
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/Kpes.h>
#include <sys/×at.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 '/print2'","r"); //执行ps -ef | grep '/test’这个命令
fread(buff,1,127,fp1); //将这个命令里的内容输出到buff数组中
pclose(fp1);
const char pattern[] = "/home/cc/linux/print2";
char *p = strstr(buff, pattern); // 字符串比较函数 看buff数组里是否有守护进程的路径
if(NULL ==p){ //若守护进程未启动
FILE *fp2 = NULL;
fp2 = popen("~/print2","r");//使用popen()函数启动
pclose(fp2);
}
sleep(6); //每隔6秒检测一次
}
return 0;
};
4、执行kill命令终止进程,再查看进程列表,发现print此时并未运行。
5、执行mymonitor,等待并查看进程列表,print此时已经继续运行。
运行结果截图:
为了更好的验证mymonitor是否能够启动print程序,所以先使用ps -ef | grep print
查看是否print在运行,如果在则杀死print进程然后再执行mymonitor
6、将编写的守护进程设置为开机自启动。
用文本编辑器创建一个新的服务单元文件,例如
/etc/systemd/system/mymonitor.service。
将以下内容添加到服务单元文件中:
Description=My Monitor Service
After=network.target
ExecStart=/home/cc/linux/mymonitor
WantedBy=default.target
保存并关闭文件。
运行以下命令以重新加载 systemd 配置:
sudo systemctl daemon-reload
运行以下命令以启用并启动服务:
sudo systemctl enable mymonitor.service
sudo systemctl start mymonitor.service
现在,mymonitor程序将在系统启动时自动运行。
开机后使用pgrep mymonitor命令查看该进程是否在运行,如下图:
选做部分:
源代码:
#include <stdio.h>
#include <stdlib.h>
#include <syslog.h>
int main() {
// 打开系统日志
openlog("mymonitor", LOG_PID, LOG_USER);
// 设置日志输出到指定文件
FILE *logFile = fopen("/tmp/mydebug", "a");
if (logFile == NULL) {
syslog(LOG_ERR, "无法打开日志文件");
closelog();
return 1;
}
int logFileDescriptor = fileno(logFile);
setlogmask(LOG_UPTO(LOG_DEBUG));
dup2(logFileDescriptor, STDERR_FILENO);
// 守护进程主体
while (1) {
// ... ... ... 0;
}
// 关闭日志文件和系统日志
fclose(logFile);
closelog();
return 0;
}
五、实验问题总结
本次实验还是比较简单的,没有遇到太多的困难,唯一一个需要注意的就是在验证mymonitor进程是否启动了print进程时候,一定要优先把print进程杀死。
这次试验对于守护进程的理解更加深刻,以下是我学习到的总结的经验:
- 守护进程的特点:守护进程是在后台运行的,没有与之相关联的终端。它们通常通过将标准输入、输出和错误重定向到文件来工作,并且不会产生与用户交互的界面。
- 创建守护进程:创建守护进程的一般步骤包括创建子进程、关闭父进程、改变工作目录、重新设置文件权限、重定向标准I/O流以及处理信号等。
- 守护进程的初始化:守护进程在初始化时需要执行一些操作,如打开日志文件、读取配置文件、初始化网络连接等。
- 守护进程的生命周期:守护进程可以在系统启动时自动加载,并在系统关闭时自动停止。它们还可以被手动启动、停止或重启。
- 守护进程的管理:Linux系统提供了一些工具和命令来管理守护进程,如systemd、init.d脚本和service命令等。
- 守护进程的日志记录:守护进程通常将其输出写入日志文件,以便记录运行状态、错误信息和其他相关信息。
- 守护进程的监控和调试:为了确保守护进程的正常运行,可以使用监控工具来检测和修复故障。调试工具可以用于追踪和分析守护进程的行为。