守护进程
1.什么是守护进程
守护进程:是一个后台运行的进程,不依附当前的终端,随着系统启动而启动,随着系统的终止而终
止,相当于window的系统服务
2.守护进程的创建的大概流程
1.创建一个孤儿进程
2.新建会话
pid_t setsid(void);
功能:创建一个新的会话,如果当前进程不是组长进程,
创建的会话id,组id就是当前pid的值
参数:
@无
返回值:成功返回pid,失败返回-1置位错误码
3.将当前进程对应的路径切换到根目录
int chdir(const char *path);
功能:切换路径的函数
参数:
@path:路径
返回值:成功返回0,失败返回-1置位错误码
4.设置umask的值
mode_t umask(mode_t mask);
功能:设置掩码
参数:
@mask:掩码的值
返回值:总是会成功,返回mask
5.进行文件描述重定向
int dup(int oldfd);
功能: dup函数的功能,拷贝fd,产生一个新的文件描述符nfd
nfd产生的原则最小为使用原则,fd和nfd都可以操作同一个文件
文件,fd和nfd共用同一个光标
参数:
@oldfd:旧的文件描述符
返回值:成功返回nfd,失败返回-1置位错误
int dup2(int oldfd, int newfd);
功能:dup2函数相当于文件描述符的重定向,
把newfd重定向到oldfd中了,以后向newfd写内容就是在向odlfd对应的文件中写内容
参数:
@oldfd:旧文件描述符
@newfd:新文件描述符
返回值:成功返回newfd,失败返回-1置位错误码
3. 守护进程的创建的代码
#include <head.h>
int main(int argc, const char* argv[])
{
pid_t pid;
pid = fork();
if (pid == -1) {
PRINT_ERR("fork error");
} else if (pid == 0) {
// 1.创建孤儿进程(退出父进程即可)
// 2.创建会话
if ((setsid()) == -1)
PRINT_ERR("setside error");
// 3.切换到根目录
if ((chdir("/") == -1))
PRINT_ERR("chdir error");
// 4.设置掩码 解决权限问题 默认的umask 为 0002
// 将umask设置为0 创建文件什么权限 实际就是什么权限
umask(0);
// 5.创建日志文件
// getdtablesize 获取进程最大的文件描述符 fd
// 保证之前的pid全部为关闭状态
for (int i = 3; i < getdtablesize(); i++) {
// 只保留 0 1 2 描述符
close(i);
}
int fd;
if ((fd = open("my.log", O_RDWR | O_APPEND | O_CREAT, 0666)) == -1)
PRINT_ERR("open my.log file error");
// 6.文件描述符重定向
dup2(fd, 0);
dup2(fd, 1);
dup2(fd, 2);
// 7.开启自己的服务
// 守护进程随着系统启动而启动
while (1) {
write(1, "i am demo\n", strlen("i am demo\n"));
sleep(1);
}
} else {
// 退出父进程
printf("parent process exit success...\n");
exit(0);
}
return 0;
}