文章目录
1,守护进程
- 守护进程(Daemon)是Linux三种进程类型(交互进程、批处理进程、守护进程)之一
- 通常在系统启动时运行,系统关闭时结束
- Linux系统中大量使用,很多服务程序(网络服务、STTP服务、打印服务、NFS服务等)以守护进程形式运行
2,守护进程的特点
- 始终在后台运行
- 独立于任何终端(既不能在终端输出,也不能在终端输入)
- 周期性的执行某种任务或等待处理特定事件
3,会话、控制终端
- Linux以会话(session)、进程组的方式管理进程
- 每个进程属于一个进程组(运行一个程序的时候,系统创建了一个进程来执行这个程序,创建进程的时候同时创建了一个新的进程组。可以理解为每个运行的程序实际上对应一个进程组,当在程序中创建子进程时,子进程和父进程同属于一个进程组)
- 会话是一个或多个进程组的集合。通常用户打开一个终端时,系统会创建一个会话。所有通过该终端运行的进 程都属于这个会话(终端成为会话的控制终端,一个会话最多能打开一个控制终端,可以不打开)
- 终端关闭时,所有相关进程会被结束(所以守护进程和终端无关,这样守护进程才能不受终端影响)
4,守护进程创建,五个步骤
a,创建子进程,父进程退出fork(),exit()
if (fork() > 0)
{
exit(0);
}
- 子进程变成孤儿进程,被init进程收养
- 子进程在后台运行(子进程虽然在后台运行,但还依附于当前终端)
b,子进程创建新会话setsid()
if (setsid() < 0)
{
exit(-1);
}
- 子进程成为新的会话组长
- 子进程脱离原先的终端
c,更改当前工作目录chdir()
chdir(“/”);//可以指向根目录
chdir(“/tmp”);//也可以指向根目录下的tmp目录
- 守护进程一直在后台运行,其工作目录不能被卸载(守护进程在创建的时候,其当前工作工作目录可能指向任意一个目录,为了避免其所在的文件系统被卸载,一般都要把守护进程的当前工作目录设指向一个永远不需要被卸载的目录,比如“/”,“/tmp”)
- 重新设定当前工作目录cwd
- 对于普通用户来说,根目录可读、可执行,但是不能写
- 所有的用户在tmp下都是可读、可写、可执行的
d,重设文件权限掩码umask()
if (umask(0) < 0)
{
exit(-1);
}
int i;
for(i=0; i<getdtablesize(); i++)
{
close(i);
}
- 关闭所有从父进程继承的打开文件(一个程序执行的时候,系统会自动打开标准输入、标准输出、标准错误三个流,这三个流都指向终端,而守护进程与终端无关,所以直接关掉。也可以重定向,把这三个流指向某个文件,然后从文件中输出或从文件中输入)
- 已脱离终端,stdin / stdout / stderr无法再使用
守护进程示例
创建守护进程,每隔1秒将系统时间写入文件time.log
int main()
{
pid_t pid;
FILE *fp;
time_t t;
int i;
if ((pid = fork()) < 0)//创建子进程
{
perror(“fork”);
exit(-1);
}
else if (pid > 0)//关闭父进程
{
exit(0);
}
setsid();//创建新会话
umask(0);//重设文件权限掩码
chdir(“/tmp”);//更改当前工作目录
for (i=0; i< getdtablesize(); i++) //关闭打开的文件描述符(从父进程继承的打开文件)
{
close(i);
}
if ((fp = fopen(“time.log”, “a”)) == NULL) {
perror(“fopen”); exit(-1); }
while ( 1 ) {
time(&t);
fprintf(fp, “%s”, ctime(&t));//将获取的系统时间自动转化为本地时间
fflush(fp);//强制刷新流
sleep(1);
}