学习进程就不得不提到一个运行在后台的特殊进程——守护进程。(也称精灵进程)。Linux系统启动时会启动很多系统服务进程,这些系统服务进程没有控制终端,不能直接和用户交互。其它进程都是在用户登录或运行程序时创建,在运行结束或用户注销时终止,但系统服务进程不受用户登录注销的影响,它们一直在运行着而我们就将这种进程称为守护进程。
守护进程独立于控制终端并周期性的执行某种任务或者等待处理某些发生的事件。守护进程是一种很有用的进程。Linux的大多数服务器就是用1守护进程实现的,比如,Internet服务器inetd、Web服务器httpd等。此外,守护进程还可以完成许多系统任务,比如作业规划进程crond等。
可以使用ps axj命令查看系统中的进程。
(由于太多只截取了一部分)
还可以使用相关参数来有选择性的查看。参数a表示不仅列当前用户的进程,也列出所有其他用户的进程,参数x表示不仅列有控制终端的进程,也列出所有无控制终端的进程,参数j表示列出与作业控制相关的信息。
使用参数x来进行查看。
了解了守护进程的概念之后,自己也可以来写一个守护进程。
创建守护进程最关键的一步是调用setsid函数创建一个新的Session,并成为Session Leader。
在调用这个函数之前,当前进程不允许是进程组的Leader,否则该函数返回-1。要保证当前进程不是进程组的Leader只要先fork再调用setsid就行了。fork创建的子进程和父进程在同一个进程组中,进程组Leader必然是该组的第一个进程,所以子进程不可能是该组的第一个进程,在子 进程中调用setsid就不会有问题了。
创建守护进程可以按照如下步骤进行:
1、 调用umask函数将文件模式创建屏蔽字设置为0;
2、调用fork,父进程退出(exit);
3、调用setsid创建一个新会话;
4.、将当前工作目录更改为根目录;
5、 关闭不在需要的文件描述符;
6.、其他:忽略SIGCHLD信号。
#include <stdio.h> #include <signal.h> #include <unistd.h> #include <stdlib.h> #include <fcntl.h> #include <sys/stat.h> void creat_daemon() { int i; int fd0; pid_t pid; struct sigaction sa; umask(0); if( (pid = fork()) < 0 ) { } else if (pid != 0) { exit(0); //终止父进程 } setsid(); //设置新会话 sa.sa_handler = SIG_IGN; sigemptyset(&sa.sa_mask); sa.sa_flags = 0; if( sigaction(SIGCHLD, &sa, NULL ) < 0 ) { return; } if( (pid = fork())<0) {printf("fork error!\n"); return; } else if( pid != 0) { exit(0); } if( chdir("/") < 0 ) {printf("child dir error\n"); return; } close(0); fd0 = open("/dev/null", O_RDWR); dup2(fd0, 1); dup2(fd0, 2); } int main() { creat_daemon(); while(1) { sleep(1); } }