Skip to content

Latest commit

 

History

History
121 lines (105 loc) · 2.76 KB

进程知识补充.md

File metadata and controls

121 lines (105 loc) · 2.76 KB

进程补充

守护进程特点

  • 后台服务进程
  • 独立于控制终端
  • 周期性执行某任务
  • 不受用户登录注销影响
  • 一般采用以d结尾的名字(服务)

进程组

PGID

  • 进程的组长
    • 组里面的第一进程
    • 进程组的ID等于进程组组长的ID
  • 进程组组长如何选择
    • 进程组中的第一个进程

会话

会话即是多个进程组

  • 创建一个会话的注意事项:
    • 不能是进程组的组长
    • 创建会话的进程成为新进程组的组长
    • 有些时候需要root权限才能创建会话
    • 创建出的新会话会丢弃原有的控制终端
  • 获取进程所属的会话ID
pid_t getsid(pid_t pid);
  • 创建进程所属的会话ID
pid_t setsid(void);

如何创建守护进程

  • fork子进程,父进程退出(必须)
  • 子进程创建新会话(必须) setsid()
  • 改变当前工作路径chdir(非必须) 适用场景: 插入U盘,在U盘中启动可执行程序。程序运行过程中U盘被拔掉了
  • 重设文件掩码 WHY?(非必须)
    • 子进程会继承父进程的掩码
    • 增加子进程的灵活性
    • 调用umask()
  • 关闭文件描述符(非必须)
  • 执行核心工作(必须)

下面是创建一个守护进程,每2s获取一次系统时间,将其写入到磁盘文件中

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <time.h>
#include <fcntl.h>
#include <string.h>
#include <sys/stat.h>
#include <signal.h>

void dowork(int no)
{
    time_t curtime;
    // 得到系统时间
    time(&curtime);
    // 格式化时间
    char *pt = ctime(&curtime);
    // 将时间写入文件
    int fd = open("/home/he/he.log", O_CREAT | O_WRONLY | O_APPEND, 0664);
    write(fd, pt, strlen(pt) + 1);
    close(fd);
}

int main(int argc, const char* argv[])
{
    pid_t pid = fork();
    if(pid > 0)
    {
        // 父进程退出
        exit(1);
    }
    else if(pid == 0)
    {
        // 创建会话成为该会话进程组的组长
        setsid();
        // 改变进程工作目录
        chdir("/home/he");
        // 重置文件掩码
        umask(0);
        // 关闭文件描述符,系统前三个自带的
        close(STDIN_FILENO);
        close(STDOUT_FILENO);
        close(STDERR_FILENO);

        // 执行核心操作
        // 注册信号捕捉
        struct sigaction act;
        act.sa_flags = 0;
        act.sa_handler = dowork;
        sigemptyset(&act.sa_mask);
        sigaction(SIGALRM, &act, NULL);
        // 创建定时器
        struct itimerval val;
        // 第一次触发的时间
        val.it_value.tv_usec = 0;
        val.it_value.tv_sec = 2;
        // 循环周期
        val.it_value.tv_usec = 0;
        val.it_value.tv_sec = 1;
        // 保证子进程处于运行状态
        while(1);
    }
    return 0;
}