进程间关系和守护进程

进程组/作业/会话的关系

进程组:进程组是一个或多个进程的集合,每个进程组有一个唯一的进程组ID,每个进程组都可以有
一个组长进程。组⻓长进程的标识是,其进程组ID等于其进程ID。 组⻓长进程可以创建一个进程组,创建该组中
的进程,然后终止。只要在某个进程组中一个进程存在,则该进程组就存在,这与其组长进程是否终止无

关。

作业:Shell分前后台来控制的不是进程而是作业或者是进程组。一个前台作业可以由多个进程组成,一个后台可以由多个进程组成,Shell可以运行一个前台作业和多个后台作业,这成为作业控制。

作业和进程组的区别:如果作业中的某个进程又创建了子进程,则子进程不属于作业。一旦作业运行结束,Shell就把自己提到前台(子进程还在,可是子进程不属于作业),如果原来的前台进程还存在(如果这个子进程还没终止),它自动变为后台进程组。在前台新起作业,shell是无法运行,因为他被提到了后台。 但是如果前台进程退出,shell就又被提到了前台,所以可以继续接受用户输入。 
会话:会话是一个或多个进程组的集合。一个会话可以有一个控制终端。这通常是登陆到其上的终端
设备(在终端登陆情况下)或伪终端设备(在网络登陆情况下)。建立与控制终端连接的会话首进程被称为
控制进程。一个会话中的⼏几个进程组可被分为一个前台进程组以及一个或多个后台进程组。所以一个会话

中,应该包括控制进程(会话首进程),一个前台进程组和任意后台进程组。

三者的关系可以理解为:一个或多个进程组组成作业,一个或多个作业组成会话。

守护进程

概念:

守护进程也称精灵进程(Daemon),是运行在后台的一种特殊进程。它独立于控制终端并且周期性地执行
某种任务或等待处理某些发生的事件。守护进程是一种很有用的进程。Linux的大多数服务器就是用守护进程
实现的。比如,ftp服务器,ssh服务器,Web服务器httpd等。同时,守护进程完成许多系统任务。比如,作
业规划进程crond等。
Linux系统启动时会启动很多系统服务进程,这些系统服务进程没有控制终端,不能直接和用户交互。其它进程
都是在用户登录或运行程序时创建,在运行结束或用户注销时终止,但系统服务进程(守护进程)不受用户登录

注销的影响,它们一直在运行着。这种进程有一个名称叫守护进程(Daemon)。

在终端下查看守护进程:ps axj | more ,凡是TPGID一栏写着-1的都是没有控制终端的进程,也就是守护进程。



创建守护进程

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

#include <unistd.h>
pid_t setsid(void);

该函数调用成功时返回新创建的Session的id(其实也就是当前进程的id),出错返回-1

注意,调用这个函数之前,当前进程不允许是进程组的Leader,否则该函数返回-1。要保证当前进程不是进 程组的Leader也很容易,要先fork再调用setsid就⾏行了。fork创建的子进程和父进程在同一个进程组中,进程组的Leader必然是该组的第一个进程,所以子程不可能是该组的第一个进程,在子进程中调用setsid就不会有问题了。

创建守护进程的步骤:

1. 调用umask将文件模式创建屏蔽字设置为0.

2. 调用fork,父进程退出(exit)。原因:1)如果该守护进程是作为一条简单的shell命令启动的,那么父进程终止使得shell认为该命令已经执行完毕。2)保证子进程不是一个进程组的组长进程。

3. 调用setsid创建一个新会话。setsid会导致:1)调用进程成为新会话的首进程。 2)调用进程成为一个进程组的组长进程 。3)调用进程没有控制终端。(再次fork一次,保证daemon进程,之后不会打开tty设备)

4. 将当前工作目录更改为根目录。

5. 关闭不在需要的文件描述符。

6. 其他:忽略SIGCHLD信号。

显示结果:




猜你喜欢

转载自blog.csdn.net/Moralin_/article/details/80036422