守护进程也叫精灵进程,是运行在后台的一种特殊进程,它独立于控制终端并且周期性的执行某种任务或等待处理某些发生的事件。Linux的大多数服务器就是用守护进程实现的,比如:ftp服务器,ssh服务器,web服务器等等。同时,守护进程完成许多系统任务。
Linux系统启动时会启动很多系统服务进程,这些系统服务进程没有控制终端,不能直接和用户交互,其他进程都是在用户登录或运行时创建,在运行结束或用户注销时终止,但系统服务进程(守护进程)不受用户登录、注销的影响,它们一直在运行着。这个进程就叫做“守护进程”。
创建守护进程:
创建守护进程最关键的一步是调用setsid函数创建一个会话,并成为一个会话leader。
#include<unistd.h>
pid_t setsid(void);
该函数调用成功时返回新创建的会话ID,其实也就是当前进程的ID,出错返回-1.
注意:调用这个函数之前,当前进程不允许是进程组的leader,否则该函数返回-1.
要保证当前进程不是进程当前组的组长可以先调用fork再调用setsid。fork创建的子进程和父进程在同一进程组中,进程组的组长必然是该组的第一个进程,所以子进程不可能是该组的第一个进程,在子进程中调用setsid就不会有问题了。
成功调用该函数的结果是:
1.创建一个新的session,当前进程称为session leader,当前进程的id就是session的id
2.创建一个新的进程组,当前进程称为进程组的leader,当前进程的id就是进程组的id
3.如果当前进程有一个控制终端,则它会失去这个控制终端,称为一个没有控制终端的进程。所谓失去控制终端是指原来的控制终端依然是打开的,仍然可以读写,但只是一个普通的打开文件而不是控制终端了。
#include<stdio.h>
2 #include<stdlib.h>
3 #include<signal.h>
4 #include<unistd.h>
5 #include<fcntl.h>
6 #include<sys/stat.h>
7
8 void mydaemon()
9 {
10 int i;
11 int fd0;
12 pid_t pid;
13 struct sigaction sa;
14
15 umask(0);
16
17 if((pid = fork())<0){
18 perror("fork");
19 }else if(pid>0){
20 exit(0);
21 }
22 setsid();
23 sa.sa_handler = SIG_IGN;
24 sigemptyset(&sa.sa_mask);
25 sa.sa_flags = 0;
26
27 if(sigaction(SIGCHLD,&sa,NULL)<0){
return ;
29 }
30 if((pid = fork())<0){
31 printf("fork error!\n");
32 return ;
33 }else if(pid!=0){
34 exit(0);
35 }
36
37 if(chdir("/") < 0){
38 printf("child dir error!\n");
39 return ;
40 }
41 close(0);
42 fd1 = open("/dev/null",O_RDONLY);
43 dup2(fd0,1);
44 dup2(fd0,2);
45 }
46
47
48 int main()
49 {
50 mydaemon();
51 while(1){
52 sleep(1);
53 }
54 }
54,1 Bot