进程编程中的守护进程
概念
- 守护进程是在后台运行不受控端控制的进程,通常情况下守护进程在系统启动时自动运行
- 守护进程的名称通常以d结尾,比如sshd、xinetd、crond等
可以利用killall 进程名字 来杀一族进程,命令很爽。。。。不需要 kill -9 pid
创建步骤
- 调用fork(),创建新进程,它会是将来的守护进程
- 在父进程中调用exit,保证子进程不是进程组组长
- 调用setsid创建新的会话期
- 将当前目录改为根目录 (如果把当前目录作为守护进程的目录,当前目录不能被卸载,它作为守护进程的工作目录了。为了避免需要卸载当前目录引起错误,所以需要修改当前的工作目录)。
- 将标准输入、标准输出、标准错误重定向到/dev/null
因为”后台任务”的标准 I/O 继承自当前 session,创建新的会话期以后并没有改变这一点。一旦”后台任务”读写标准 I/O,就会发现它已经不存在了(属于之前的会话期),所以就报错终止执行。
为了解决这个问题,需要对”后台任务”的标准 I/O 进行重定向。
API
- 函数原型:int daemon(int nochdir, int noclose);
- 功能:创建一个守护进程
- 参数:
- nochdir:=0将当前目录更改至“/”
- noclose:=0将标准输入、标准输出、标准错误重定向至“/dev/null”
使用该函数不需要按照上述的五步骤去创建守护进程,C库函数帮我们做了大量的工作!
- 函数原型:pid_t setsid(void);
- 功能:Setsid创建一个新的会话;调用者进程会是这个会话期唯一的一个进程,是唯一组的组长;调用者进程id是组id,也是会话期的id。不能用进程组组长去调用setsid函数
返回值:成功返回调用者进程的新会话期的ID/进程组ID,失败返回-1
运行
ps -ef
命令
root 2445 1208 0 19:49 ? 00:00:00 sshd: zhenjunliu [priv]
zhenjun+ 2500 2445 0 19:49 ? 00:00:00 sshd: zhenjunliu@notty
zhenjun+ 2503 2500 0 19:49 ? 00:00:00 /usr/lib/openssh/sftp-server
zhenjun+ 2522 2441 0 19:49 ? 00:00:00 sshd: zhenjunliu@pts/5
zhenjun+ 2523 2522 0 19:49 pts/5 00:00:00 -bash
root 5625 2 0 22:05 ? 00:00:01 [kworker/0:2]
root 5988 2 0 22:21 ? 00:00:00 [kworker/3:0]
有的进程有tty,有的进程没有tty。带问号的是守护进程。
会话期和进程组
- 会话期:是一个或者多个进程组的集合,通常一个会话期开始于用户登录,终止于用户退出。在此期间,该用户运行的所有进程都属于这个会话期。
- 一个会话期里面可能有多个进程,这些进程就是一个进程组!每个组有一个组长!组长的PID就是进程组ID。
示例代码
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <signal.h>
#include <errno.h>
#include <signal.h>
#include <sys/stat.h>
#include <fcntl.h>
int my_daemon(int nochdir, int noclose)
{
int i = 0;
pid_t pid;
pid = fork();
if (pid == -1)
{
perror("fork err");
exit(0);
}
if (pid > 0)
{
exit(0);
}
printf("pid:%d \n", getpid());
pid = setsid();
if (pid == -1)
{
perror("fork err");
exit(0);
}
if (nochdir != 0)
chdir("/");
if (noclose != 0)
{
for (i=0; i<3; i++)
{
close(i);
}
}
open("/dev/null", O_RDWR);
dup(0);
dup(1);
while(1)
{
sleep(1);
}
printf("hello\n");
return 0;
}
int main()
{
my_daemon(1, 1);
return 0;
}
关于守护进程的更多了解参见:http://blog.chinaunix.net/uid-20937170-id-5748313.html