1、课程目标
- 守护进程特点(了解)
- 会话、控制终端(了解)
- 创建守护进程(熟练)
- 小结
2、守护进程
Linux三种进程类型分别是交互进程、批处理进程、守护进程(Daemon)。
交互进程:由一个shell启动的进程。交互进程既可以在前台运行,也可以在后台运行,有输入有输出。
守护进程:Linux系统启动时启动的进程,并在后台运行。生命周期长,系统关闭,才会结束。
批处理进程是一个进程序列,和终端没有联系。
3、守护进程特点
- 始终在后台运行。
- 独立于任何终端,不能在终端输入输出。
- 周期性的执行某种任务或等待处理特定事件
4、守护进程-会话、控制终端
- Linux以会话(session)、进程组的方式管理进程
- 每一个进程属于一个进程组,子进程属于父进程的进程组。
- 会话是一个或多个进程组的集合。通常用户打开一个终端时,系统会创建一个会话。所有通过该终端运行的进程都属于这个会话。(当打开一个终端时,shell进程启动,成为会话组的组长,在shell创建的所有的进程都属于该会话。这个终端称为会话的控制终端。一个会话最多打开一个控制终端,控制终端关闭后,依附于该终端的进程都会结束。)
5、守护进程创建(一)
- 创建子进程、父进程退出
if(fork()>0)
{
exit(0);//结束父进程,保留子进程
}
- 子进程变成孤儿进程,被init进程收养
- 子进程会自动在后台运行,但会依附于终端。(终端关闭则子进程结束)
6、守护进程创建(二)
- 子进程创建新的会话
if(setsid()<0)
{
exit(-1);
}
- 子进程称为新的会话的组长,不再属于原先的会话
- 子进程脱离原来的终端
7、守护进程创建(三)
- 更改当前的工作目录
chdir("/");//权限不同,普通用户可执行,不可写
chdir("/tmp");//所有用户可读可写可执行
- 守护进程一直在后台运行,其工作目录不能被卸载,所以需要修改工作目录
8、守护进程创建(四)
- 重新设定文件权限掩码
if(umask(0) < 0)
{
exit(-1);
}
- 文件权限掩码设置成0,不会对权限进程屏蔽。
- 权限掩码设定是对当前进程有效
9、守护进程创建(五)
- 关闭打开的文件描述符
int i;
for(i = 0; i < getdtablesize(); i++)
{
close(i);
}
getdtablesize()返回一个进程可以拥有的最大打开文件数,可能比文件描述符的最大值多一个。
- 关闭所有从父进程继承的打开文件
- 以脱离终端。stdin/stdout/stderr无法再使用。
10、守护进程-示例
示例目标:创建守护进程,每隔1s将系统时间写入文件time.log
#include <stdio.h>
#include <sys/types.h>//fork
#include <unistd.h>
#include <sys/stat.h>//umask
#include <stdlib.h>//exit
int main(void)
{
pid_t pid;
FILE *fp;
int count = 0;
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)
{
count++;
fprintf(fp,"%d\t",count);//将累加的数值写入文件
fflush(fp);//刷新流,写入文件
sleep(1);//睡眠1s
}
}
- 最后查看结果需要在/temp目录中查看其中的time.log文件是否数据累加的写入。
11、进程小结
- 守护进程的特点
- 守护进程创建步骤