守护进程
守护进程特点:
- 运行周期长;
- 在后台执行,不需要和用户进行交互。
在windows上称为服务。
会话:
终端的打开会伴随着会话的建立,直到exit退出终端会话才会结束。
会话首进程:
在会话中运行的第一个进程就是首进程。
在终端中,bash就是第一个进程(会话首进程)。
进程组:
在终端中执行命令,就会创建一个进程组,是进程组中唯一的进程。
当命令结束时,整个进程组就会消失。
一个进程组中可以包含一个进程,也可以包含两个或多个进程。
组长进程:
父进程(组长进程),子进程(组员进程)。
守护进程创建
创建新会话的进程一开始必须是一个普通的组员进程。
用进程id号标识整个会话的id。
尽管退出终端,进程也能继续在后台去执行,这个程序必须脱离原来的会话,创建新会话。
编程思路:
- fork( ) ,产生一个子进程,退出父进程(原因:保证是一个普通的组员进程)。
- setsid( ) ,创建新会话。
- fork( ),退出父进程,失去会话首进程和进程组组长的身份。(这一步可做可不做,起保险作用)
- chdir("/"),将路径改到根目录下。
- umask(0),清空掩码。
- close(), 关闭所有描述符。
- 如果产生子进程就要处理僵死进程。
向一个文件中周期性的写入数据(日志文件)
守护进程后缀一般以 d 结尾。
一个进程打开的文件描述符是有限的。
1 #include<stdio.h>
2 #include<stdlib.h>
3 #include<unistd.h>
4 #include<string.h>
5 #include<time.h>
6 #include<sys/stat.h>
7
8 void set_demon() //设置为守护进程,守护进程后缀一般以"d"结尾
9 {
10 pid_t pid=fork();
11 if(pid!=0)//如果不是子进程,程序退出
12 {
13 exit(0);
14 }
15
16 setsid();//创建新会话
17
18 pid=fork();
19 if(pid!=0)
20 {
21 exit(0);
22 }
23
24 chdir("/"); //将当前的路径改到根目录下
25
26 umask(0);//清掉掩玛的权限,应该是什么权限就是什么权限
27 int size=getdtablesize();//得到可以打开文件描述符的数目
28 for(int i=0;i<size;i++)
29 {
30 close(i);
31 }
32 }
33
34 int main()
35 {
36 set_demon();//设置为守护进程
37 while(1)
38 {
39 FILE*fp=fopen("/tmp/c215.log","a");//根目录tmp下,除了家目录以外,任何用户都可以创建文件。 a 以追加方式打开文件
40 if(fp==NULL)
41 {
42 break;
43 }
44
45 time_t tv; //获取当前时间
46 time(&tv);//存的时间值为秒数
47 fprintf(fp,"time is:%s", asctime(localtime(&tv)));//转换为本地时间,写入文件中
48 fclose(fp);
49
50 sleep(5);
51
52 }
53 }