linux 守护进程
2012-05-03 19:42
141 查看
重点是要理解linux的终端和会话机制。
fork()将终端交给子进程,然后主进程退出,setsid()使子进程成为sessionleader。
改变文件符号。
用
凡是
创建守护进程最关键的一步是调用
该函数调用成功时返回新创建的Session的id(其实也就是当前进程的id),出错返回-1。注意,调用这个函数之前,当前进程不允许是进程组的Leader,否则该函数返回-1。要保证当前进程不是进程组的Leader也很容易,只要先
成功调用该函数的结果是:
创建一个新的Session,当前进程成为Session Leader,当前进程的id就是Session的id。
创建一个新的进程组,当前进程成为进程组的Leader,当前进程的id就是进程组的id。
如果当前进程原本有一个控制终端,则它失去这个控制终端,成为一个没有控制终端的进程。所谓失去控制终端是指,原来的控制终端仍然是打开的,仍然可以读写,但只是一个普通的打开文件而不是控制终端了。
为了确保调用
运行这个程序,它变成一个守护进程,不再和当前终端关联。用
参考:http://learn.akae.cn/media/ch34s03.html
fork()将终端交给子进程,然后主进程退出,setsid()使子进程成为sessionleader。
改变文件符号。
用
ps axj命令查看系统中的进程。参数
a表示不仅列当前用户的进程,也列出所有其他用户的进程,参数
x表示不仅列有控制终端的进程,也列出所有无控制终端的进程,参数
j表示列出与作业控制相关的信息。
凡是
TPGID一栏写着-1的都是没有控制终端的进程,也就是守护进程。在
COMMAND一列用
[]括起来的名字表示内核线程,这些线程在内核里创建,没有用户空间代码,因此没有程序文件名和命令行,通常采用以
k开头的名字,表示Kernel。
init进程我们已经很熟悉了,
udevd负责维护
/dev目录下的设备文件,
acpid负责电源管理,
syslogd负责维护
/var/log下的日志文件,可以看出,守护进程通常采用以
d结尾的名字,表示Daemon。
创建守护进程最关键的一步是调用
setsid函数创建一个新的Session,并成为Session Leader。
该函数调用成功时返回新创建的Session的id(其实也就是当前进程的id),出错返回-1。注意,调用这个函数之前,当前进程不允许是进程组的Leader,否则该函数返回-1。要保证当前进程不是进程组的Leader也很容易,只要先
fork再调用
setsid就行了。
fork创建的子进程和父进程在同一个进程组中,进程组的Leader必然是该组的第一个进程,所以子进程不可能是该组的第一个进程,在子进程中调用
setsid就不会有问题了。
成功调用该函数的结果是:
创建一个新的Session,当前进程成为Session Leader,当前进程的id就是Session的id。
创建一个新的进程组,当前进程成为进程组的Leader,当前进程的id就是进程组的id。
如果当前进程原本有一个控制终端,则它失去这个控制终端,成为一个没有控制终端的进程。所谓失去控制终端是指,原来的控制终端仍然是打开的,仍然可以读写,但只是一个普通的打开文件而不是控制终端了。
#include <stdlib.h> #include <stdio.h> #include <fcntl.h> void daemonize(void) { pid_t pid; /* * Become a session leader to lose controlling TTY. */ if ((pid = fork()) < 0) { perror("fork"); exit(1); } else if (pid != 0) /* parent */ exit(0); setsid(); /* * Change the current working directory to the root. */ if (chdir("/") < 0) { perror("chdir"); exit(1); } /* * Attach file descriptors 0, 1, and 2 to /dev/null. */ close(0); open("/dev/null", O_RDWR); dup2(0, 1); dup2(0, 2); } int main(void) { daemonize(); while(1); }
为了确保调用
setsid的进程不是进程组的Leader,首先
fork出一个子进程,父进程退出,然后子进程调用
setsid创建新的Session,成为守护进程。按照守护进程的惯例,通常将当前工作目录切换到根目录,将文件描述符0、1、2重定向到
/dev/null。Linux也提供了一个库函数
daemon(3)实现我们的
daemonize函数的功能,它带两个参数指示要不要切换工作目录到根目录,以及要不要把文件描述符0、1、2重定向到
/dev/null。
运行这个程序,它变成一个守护进程,不再和当前终端关联。用
ps命令看不到,必须运行带
x参数的
ps命令才能看到。另外还可以看到,用户关闭终端窗口或注销也不会影响守护进程的运行。
参考:http://learn.akae.cn/media/ch34s03.html
相关文章推荐
- Linux 的进程组、会话、守护进程
- Linux 守护进程的原理与实现
- 深入理解Linux守护进程
- Linux守护进程的编程实现
- linux 守护进程编程
- linux下的守护进程daemon
- linux守护进程实现
- Linux守护进程设计
- Linux 守护进程三
- linux守护进程解读
- linux创建守护进程
- linux编程-守护进程编写
- Linux Daemon(守护进程)
- Linux守护进程之Supervisor
- Linux守护进程
- Linux 命令详解(六)Linux 守护进程的启动方法
- Linux编程之守护进程
- Linux守护进程的编程实现
- linux 怎样生成守护进程
- linux守护进程