linux 之守护进程

会话用来管理前后台进程组。
会话一般关联着一个终端。
关闭一个终端,它对应的会话中的所有进程都会被关闭。

守护进程

不受终端影响,就算终端退出,也可以继续在后台运行。

如何写一个守护进程

  • 1、创建一个子进程,让父进程直接而退出(避免父进程一直占有终端的使用权,那样shell才有终端的使用权限)。
    可以通过fork() 函数。
  • 2、创建一个新的会话,子进程需要在一个新的会话里面,那样才不受当前终端影响,摆脱当前终端。
    通过setsid()函数
  • 3、改变守护进程的当前工作目录,改为“ / ”,当父进程使用fork() 函数生成子进程时,子进程的当前工作目录就是这个父进程的工作目录。
    通过chrdir() 函数来实现
  • 4、重设文件权限掩码,新建文件的权限收到文件权限掩码的影响,可以使用 shell指令 “ umask ”来查看文件权限掩码的值。结果0022 表示只写,当前用户,用户组的,其他用户的。新建默认是666,与umask的掩码值进行与(~umask码),得到最终的644。
    通过umask()函数可以直接重设umask值。
  • 5、关闭不需要的文件描述符。0,1,2:标准输入,标准输出,标准出错。这三都是直接和终端相关联的。因为希望守护进程完全脱离终端的影响。通过close()关闭这三个文件描述符即可。

测试程序

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<fcntl.h>
#include<sys/types.h>
#include<unistd.h>
#include<sys/wait.h>
#include<sys/stat.h>

#define MAXFILE		3

int main()
{
	pid_t pid;
	int fd,len,i,num;
	char *buf = "The daemon is running.\n";

	len = strlen(buf) + 1;
	//创建子进程,销毁父进程
	pid = fork();
	if(pid < 0)
	{
		puts("fork fail");
		exit(1);
	}
	if(pid > 0)
	{
		exit(0);
	}
	//创建新会话,摆脱终端的影响
	setsid();
	//改变当前工作目录
	chdir("/");
	//重设文件权限掩码
	umask(0);
	//关闭文件的默认描述符
	for(i=0;i<MAXFILE;i++)
	{
		close(i);
	}
	//实现守护进程的功能
	while(1)
	{
		//fd = open("./daemon.log",O_CREAT | O_WRONLY | O_APPEND,0666);
		//我一开始用上面这个相对目录,似乎无法创建文件,
		//改成下面的绝对路径文件创建、写成功。
		fd = open("/home/jl/test/daemon.log",O_CREAT | O_WRONLY | O_APPEND,0666);
		write(fd,buf,len);
		close(fd);
		sleep(5);
	}	
}

实验结果

关闭当前终端,打开一个新的终端

jl@jl-virtual-machine:~/test$ ls
a.out  dae.c  daemon.log  dsadsa.c  epit  exit.c  fscanf.c  precise  stack.c  test  tt1.c  tt.c  wait.c
jl@jl-virtual-machine:~/test$ 
jl@jl-virtual-machine:~/test$ 
jl@jl-virtual-machine:~/test$ ps aux | grep  a.out 
jl        15237  0.0  0.0   4380    72 ?        Ss   00:15   0:00 ./a.out
jl        15432  0.0  0.0  16180  1064 pts/0    R+   00:17   0:00 grep --color=auto a.out
jl@jl-virtual-machine:~/test$ 
jl@jl-virtual-machine:~/test$ 
jl@jl-virtual-machine:~/test$ 
jl@jl-virtual-machine:~/test$ 
jl@jl-virtual-machine:~/test$ 
jl@jl-virtual-machine:~/test$ 
jl@jl-virtual-machine:~/test$ cat daemon.log 
The daemon is running.
The daemon is running.
The daemon is running.
jl@jl-virtual-machine:~/test$ 
jl@jl-virtual-machine:~/test$ 
jl@jl-virtual-machine:~/test$ cat daemon.log 
The daemon is running.
The daemon is running.
The daemon is running.
The daemon is running.
The daemon is running.
The daemon is running.
The daemon is running.
The daemon is running.
The daemon is running.
jl@jl-virtual-machine:~/test$

可以看到log文件成功产生,该进程依然存在,并且不断地往log文件里面写log。
测试成功!

普通进程伪装成守护进程(不是真正的,有细微的差别):

shell指令 “ nohub ”

nohub sleep 1000 &

关闭当前终端,在另一个终端里面使用

ps aux | grep sleep

发现该进程依然存在。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值