Linux操作系统-实验三 守护进程

目录

一、实验目的

二、实验内容

三、实验具体分工

四、实验步骤、源程序及结果截图

1、编写print.c

2、编写守护进程mymonitor.c

3、 首先验证print是否能正常运行,需要执行print,然后查看系统时间是否正常输出至trush.txt。

4、执行kill命令终止进程,再查看进程列表,发现print此时并未运行。

5、执行mymonitor,等待并查看进程列表,print此时已经继续运行。

6、将编写的守护进程设置为开机自启动。

五、实验问题总结

  


一、实验目的

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进程杀死。

       这次试验对于守护进程的理解更加深刻,以下是我学习到的总结的经验:

  1. 守护进程的特点:守护进程是在后台运行的,没有与之相关联的终端。它们通常通过将标准输入、输出和错误重定向到文件来工作,并且不会产生与用户交互的界面。
  2. 创建守护进程:创建守护进程的一般步骤包括创建子进程、关闭父进程、改变工作目录、重新设置文件权限、重定向标准I/O流以及处理信号等。
  3. 守护进程的初始化:守护进程在初始化时需要执行一些操作,如打开日志文件、读取配置文件、初始化网络连接等。
  4. 守护进程的生命周期:守护进程可以在系统启动时自动加载,并在系统关闭时自动停止。它们还可以被手动启动、停止或重启。
  5. 守护进程的管理:Linux系统提供了一些工具和命令来管理守护进程,如systemd、init.d脚本和service命令等。
  6. 守护进程的日志记录:守护进程通常将其输出写入日志文件,以便记录运行状态、错误信息和其他相关信息。
  7. 守护进程的监控和调试:为了确保守护进程的正常运行,可以使用监控工具来检测和修复故障。调试工具可以用于追踪和分析守护进程的行为。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值