进程的层次

进程:每个进程都有父进程,父进程也有父进程,这样就形成了一个以init进程为根的家族树。

进程还有其他层次关系:进程,进程组会话。

pid:进程唯一的标识。对于多线程的进程而言,所有线程调用getpid()函数会返回相同的值。

进程组:一个或多个进程的集合。

ps -ejH 查看进程组。

pgid:进程组id,每个进程都有进程组id,子进程会继承父进程的进程组id.

进程组之间的关系表示

ps和grep都是bash创建的子进程,两者通过管道协同完成一项工作,他们隶属于同一个进程组,ps是组长。

修改进程组ID的接口如下:

#include <unistd.h>
int setpgid(pid_t pid, pid_t pgid);
这个函数的含义是,找到进程ID为pid的进程,将其进程组ID修改为pgid,如果pid的值为0,则表示要修改调用进程的进程组ID。该接口一般用来创建一个新的进程组。”

sid:会话id,每个进程都会有会话id,子进程会继承父进程的会话id.

ps axjf 查看进程会话

会话是一个或多个进程组的集合,以用户登录系统为例。
进程组与会话的关系

用户登录linux时,登录进程会为这个用户创建一个会话,用户登录的shell就是会话的手进程,会话的首进程id会作为整个会话id.

登录shell时,用户可能使用管道,让多个进程互相配合完成工作,这一组进程属于同一个进程组。

系统提供setsid函数来创建会话,其接口定义如下:

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

如果一个函数的调用进程不是进程组组长,那么调用该函数会发生以下事情:

1)创建一个新会话,会话ID等于进程ID,调用进程成为会话的首进程。

2)创建一个进程组,进程组ID等于进程ID,调用进程成为进程组的组长。

3)该进程没有控制终端,如果调用setsid前,该进程有控制终端,这种联系就会断掉。

调用setsid函数的进程不能是进程组的组长,否则调用会失败,返回-1,并置errno为EPERM。
 

猜你喜欢

转载自blog.csdn.net/weixin_42365095/article/details/82884744