目录
一、 守护进程
1.1 进程组
- 多个进程的一个集合。
- 在linux所有的进程都属于某一个进程组。
- 当前进程组中的第一个进程, 就是组长
进程组ID和组长的进程ID相同
获取当前进程所在的进程组的组ID
pid_t getpgrp(void);
获取指定进程所在的进程组的组ID
pid_t getpgid(pid_t pid);
- pid: 指定的进程的PID
将一个进程送到另外的一个进程组,创建一个新的进程组
int setpgid(pid_t pid, pid_t pgid);
- pid: 要操作的进程的PID
- pgid: 进程组ID
1.2 会话
多个进程组的集合.
// 获取进程所属的会话ID
#include <unistd.h>
pid_t getsid(pid_t pid);
返回值:
成功: 会话ID, 失败: -1
#include <unistd.h>
// 创建一个会话
// 在哪个进程中调用该函数, 这个进程就会被提升为会话
// - 没有任何职务的进程才满足条件, 普通的进程
// - 这个普通的进程会脱离原来的操作终端
pid_t setsid(void);
- > - 不能是进程组长
- > - 创建会话的进程成为新进程组的组长
- > - 创建出的新会话会丢弃原有的控制终端
1.3 创建守护进程的步骤
红色为必须步骤
- 1. 父进程创建子进程, 杀死父进程 -> 必须
- 2. 将子进程提升为会话 -> 必须
setsid();
- 3. 修改进程的工作目录, 工作目录切换到不能被卸载的目录中: / /home -> 不是必须
目的: 防止有些不安全目录被卸载:
在U盘总启动一个进程, 把U盘拔了, 进程无法正常运行
chdir();
- 4. 修改umask掩码 -> 不是必须
umask();
- 5. 关闭/重定向文件描述符 -> 不是必须
- 标准输入 -> close(0)
- 标准输出 -> close(1)
- 标准错误 -> close(2)
- 重定向: 设备文件: /dev/null ->int fd = open("/dev/null", O_RDWR);
dup2(0, fd)
- 6. 核心操作流程 -> 必须
例子:写一个守护进程, 每隔2s获取一次系统时间, 将这个时间写入到磁盘文件.
#include <stdio.h>