linux系统编程-守护进程、后台进程、 精灵进程 、daemon

linux中守护进程又称:后台进程、 精灵进程 、daemon

1.特点:

   在后台运行的进程,生命周期长,一般情况下在系统开机的时候启动,在关机的时候结束

2.作用:

   周期性的处理某些事情,或者执行某些任务。

3.名词:

   进程:PID

   父进程:创建子进程的进程PPID

   进程组:同类型的进程组成的进程组。PGID

   会话组:同类型的进程组成的,SID

如何创建一个守护进程

4.思路:

  1. 确定它的人物
  2. 和终端脱离关系
  3. 确保当前守护进程的依赖目录不被卸载
  4. 根据当前的检测结果分类提示 msgbox   写日志。
  5. 考虑从父进程

5.创建守护进程:

5.1.创建子进程,父进程退出 

当前子进程不是进程组组长,这样自己就不是进程组的组长

相关函数:fork()

5.2.创建新的会话组(脱离控制终端)

它创建新的会话组,它是会话组的组长,它是进程组的组长,该组内只有一个进程,该会话组内只有一个进程,并且没有控制终端。

在这里使用的是系统函数setsid()来创建一个新的会话,并且担任该会话组的组长,摆脱原会话的控制==》摆脱原进程的控制==》摆脱原控制终端的控制。

相关函数:setsid();

5.3.切换工作路径             

一般切换到,根目录,因为根目录不会被卸载。

相关函数:chdir(“/”);

5.4.更新文件权限掩码       

文件权限掩码是屏蔽掉文件权限中的对应位。由于使用fork()函数新创建的子进程继承了父进程的文件权限掩码,这就给该子进程使用文件带了很多的麻烦(比如父进程中的文件没有执行文件的权限,然而在子进程中希望执行相应的文件这个时候就会出问题)。因此在子进程中要把文件的权限掩码设置成为0,即在此时有大的权限,这样可以大大增强该守护进程的灵活性

相关函数: umask(0);

5.5.关闭不需要的文件描述符,等需要的时候再重新打开。

maxFd = getdtablesize();

for(fd =0 ;fd <= maxFd;fd++)
{
       close(fd);
}

5.6.做自己的事情

while(1)
{
    /* do */
}

5.7.查看守护进程状况:

一般守护进程会在最下面显示。

yuupeng@ubuntu:~/test$ gcc Deamon.c -o my_deamon
yuupeng@ubuntu:~/test$ ./my_deamon   /*执行会创建守护进程*/

yuupeng@ubuntu:~/test$ ps axj | head -n1
 PPID   PID  PGID   SID TTY      TPGID STAT   UID   TIME COMMAND
yuupeng@ubuntu:~/test$ ps axj | tail -n5
    2  3583     0     0 ?           -1 S        0   0:00 [kworker/0:1]
    2  3697     0     0 ?           -1 S        0   0:00 [kworker/0:0]
    1  4041  4041  4041 ?           -1 Ss    1000   0:00 ./my_deamon  /*守护进程*/
 3273  4073  4073  3273 pts/5     4073 R+    1000   0:00 ps axj
 3273  4074  4073  3273 pts/5     4073 S+    1000   0:00 tail -n5

yuupeng@ubuntu:~/test$ kill 4041  /*退出守护进程进程号:4041*/

yuupeng@ubuntu:~/test$ ps axj | tail -n4 /*再次检查守护进程信息*/
    2  3583     0     0 ?           -1 S        0   0:00 [kworker/0:1]
    2  3697     0     0 ?           -1 S        0   0:00 [kworker/0:0]
 3273  4082  4082  3273 pts/5     4082 R+    1000   0:00 ps axj
 3273  4083  4082  3273 pts/5     4082 S+    1000   0:00 tail -n5
yuupeng@ubuntu:~/test$ 

6.例程

/*守护进程 */

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

int main()
{
	pid_t  pid =0;
	int  fd=0;
	int  maxFd=0;
	char *buf = "yuupeng";
	//创建一个子进程,父进程退出
	pid = fork();
	if(pid < 0)
	{
		perror("Fork error\n");
		return -1;
	}else if(pid > 0)
	{
	   exit(0);
	}
	printf("创建子进程成功");
	//创建会话组,只有不是进程组的组长则 setsid(); 才会成功
	setsid();
	//切换工作路径
	chdir("/tmp");
	//修改文件权限
	umask(0);
	//关闭不需要的文件描述符
	maxFd = getdtablesize();
	for(fd =0 ;fd < maxFd;fd++)
	{
	   close(fd);
	}
	//做自己的事情
	while(1)
	{
        /*在目录 /tmp 下守护进程会给1.txt创建文件*/
		if((fd = open("1.txt",O_CREAT|O_WRONLY|O_TRUNC,0600))<0)
		{
			printf("Open file error \n");
			exit(1);
		}
	
	    while(1){
            /* 循环的给 目录 /tmp/1.txt 这个文件写数据 */
			write(fd,buf,strlen(buf));
			sleep(1);
		}
		close(fd);
		
	}
	exit(0);
   
    return 0;
}

猜你喜欢

转载自blog.csdn.net/yuupengsun/article/details/106291131