linux系统-会话及守护进程

会话

多个进程组的集合

创建一个会话需要注意的点:

  • 调用进程不能是进程组组长,该进程变成会话首进程(session header)「
  • 该进程成为一个新进程组的组长进程
  • 需要root权限(ubuntu不需要)
  • 新会话丢弃原有的控制终端,该会话没有控制终端
  • 该调用进程是组长进程,则出错返回
  • 建立新会话时,先调用fork,父进程终止,子进程调用setsid

setsid函数:

创建一个会话, 并以自己的ID设置进程组ID, 同时也是新会话的ID

1
2
pid_t setsid(void);
//成功返回调用进程的会话ID, 失败返回-1并设置errno

调用了setsid函数的进程, 既是新的会长, 也是新的组长

守护进程

Daemon(精灵)进程,是Linux中的后台服务进程通常独立于控制终端并且周期性地执行某种任务或等待处理某些发生的事件。一般采用d结尾的名字。

Linux后台的一些系统服务进程,没有控制终端,不能直接和用户交互。不受用户登录、注销的影响,一直在运行。这些进程属于守护进程。如:预读入缓输出机制的实现,ftp服务器,nfs服务器等。

创建守护进程,最关键的步骤:调用setsid函数创建一个新的Session,并成为Session Leader.

创建守护进程

  • 创建子进程, 父进程退出: 所有工作在子进程中形式上脱离了控制终端

  • 在子进程中创建新会话: setsid()函数, 使子进程完全独立出来, 脱离控制

  • 改变当前工作目录位置: chdir()函数, 防止占用可卸载的文件系统

  • 重设文件权限掩码: umask()函数, 防止继承的文件创建屏蔽字拒绝某些权限

  • 关闭文件描述符: 继承的打开文件不会用到, 浪费系统资源, 无法卸载

  • 开始执行守护进程核心工作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
//创建守护进程
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>


int main(int argc,char* argv[]){
pid_t pid=0;
int ret=0;
int fd=0;

pid=fork();
if(pid>0)
exit(0);

/*创建新会话*/
pid=setsid();
if(pid==-1)
perr_exit("setsid error");

ret=chdir("/home/dongshifu");
if(ret==-1)
perr_exit("chdir error");

/*重设文件权限掩码*/
umask(0022);

/*关闭标准输入*/
close(STDIN_FILENO);

/*将标准输出和标准出错重定向到文件黑洞*/
fd=open("/dev/null",O_RDWR);
if(fd==-1)
perr_exit("open error");
dup2(fd,STDOUT_FILENO);
dup2(fd,STDERR_FILENO);

/*模拟业务逻辑*/
while(1);

return 0;
}