@okokme
2018-07-31T01:28:15.000000Z
字数 2305
阅读 473
Linux系统编程之进程
Daemon(守护进程)是运行在后台的一种特殊进程.没有控制终端与之相连.
特点:独立于终端控制,周期性地执行某种任务
守护进程启动方式: 从启动脚本/etc/rc.d; 由作业规划crond启动; 又用户终端(通常是shell)执行
编写守护进程要点:
* 让程序在后台执行.方法是fork产生一个子进程,然后使得父进程退出.
pid_t pid;
pid = fork();/*产生子进程*/
if(pid > 0)
exit(0); /*结束父进程使得子进程成为后台进程*/
else if(pid < 0)
exit(-1);
1 #include<stdio.h>
2 #include<unistd.h>
3 #include<sys/types.h>
4
5 int main() {
6 pid_t pid;
7
8 if ((pid=fork())<0) {
9 printf("fork error!");
10 exit(1);
11 }else if (pid==0) {
12 printf("The child process PID is %d.\n",getpid());
13 printf("The Group ID of child is %d.\n",getpgid(0));
14 printf("The Session ID of child is %d.\n",getsid(0));
15 sleep(10);
16 setsid(); // 子进程非组长进程,故其成为新会话首进程,且成为组长进程。该进程组id即为会话进程
17 printf("Changed:\n");
18 printf("The child process PID is %d.\n",getpid());
19 printf("The Group ID of child is %d.\n",getpgid(0));
20 printf("The Session ID of child is %d.\n",getsid(0));
21 sleep(20);
22 exit(0);
23 }
return 0;
}
pid_t setsid(void);
该调用进程是组长进程,则出错返回
该调用进程不是组长进程,则创建一个新会话
该进程变成新会话首进程(session header)
该进程成为一个新进程组的组长进程。
该进程没有控制终端,如果之前有,则会被中断
组长进程不能成为新会话首进程,新会话首进程必定会成为组长进程
在子进程中调用setsid()后,子进程成为新会话首进程,且成为一个组长进程,其进程组id等于会话id,进程可以通过setpgid()来加入已存在的进程组或创建一个新的进程组。
```
/*建立新进程组在这个新进程组中,子进程成为这个进程组的首进程以使该进程脱离所有终端*/
setsid();//因为上边已经结束了父进程使子进程成为后台进程,所以可以直接调用setsid
````
/*在新建的会话中,再次建立一个子进程(孙子),退出该父进程(儿子),保证了该进程(新孙子进程)不是进程组长,同时让该进程无法打开一个新的终端(无组长无法重新申请打开终端)*/
pid = fork();
if(pid > 0)
exit(0);
else if(pid <0)
return -1;
/*先得到最高文件描述符,然后用一个循环程序,关闭0到最高文件所有的文件描述符*/
for(i=0; i<NOFILE; close(i++));
/*将当前目录改为根目录,使进程不与任何文件系统联系*/
chdir("/");
/*将文件屏蔽字设为0*/
umask(0);
处理SIGCHLD信号,在Linux下,可以简单将SIGCHLD信号操作设成SIG_IGN,这样子进程结束时候不会产生僵尸进程.
/*忽略SIGCHLD信号*/
singnal(SIGCHLD,SIG_IGN);
ps -ef查看进程状态
注:ps -ef查看进程状态
守护进程没有控制终端,因此当某些情况发生时,不管是一般的报告性信息,还是需由管理员处理的紧急信息,都需要以某种方式输出。Syslog 函数就是输出这些信息的标准方法,它把信息发送给 syslogd 守护进程。
Linux大多数服务都是通过守护进程实现的,完成许多系统任务
让某个进程不因为用户、终端或者其他的变化而受到影响,那么就必须把这个进程变成一个守护进程.
编写守护进样实际上是把一个普通进程按照上述的守护进程的特性改造成为守护进程。