进程间关系

一、进程组:一个或多个进程的集合。通常,它们与一作业相关联,可以接收来自同一终端的信号。每个进程组有唯一的进程组ID。每个进程有一个组长进程,其进程ID就是进程组ID。
组长进程可以创建一个进程组,创建该组中的进程,然后终止。只要进程组中有一个进程存在,进程组就一直存在,与其组长是否存在无关。
用代码创建一个进程组:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

#define ERR_EXIT(m) \
    do\
    {\
        printf(m);\
        exit(EXIT_FAILURE);\
    }while(0)

int main()
{
    pid_t pid;
    if((pid = fork()) < 0)
        ERR_EXIT("fork");

    else if(pid == 0)
    {
        if(fork() < 0)
            ERR_EXIT("fork");
        while(1);
    }
    else
    {
        sleep(10);
        printf("process group quit\n");
        exit(EXIT_SUCCESS);
    }

    return 0;
}

最先存在的进程为进程组组长,创建子进程后,父进程10秒后退出,子进程继续创建一个子进程后一直执行死循环操作。当进程组组长退出后,这个进程组依然存在:
这里写图片描述

二、作业:一个作业也可以说是一个任务,可以由一个或多个进程组成,可以理解为相当于一个进程组所执行的功能,但是又与进程组有区别。
作业与进程组区别:如果作业中某个进程有创建了子进程,则子进程不属于此作业。
我们知道shell有前台进程和后台进程,实质上正真有前后台区分的是作业(或进程组)。shell可以同时运行一个前台作业和任意多个后台作业,这称为作业控制
在前台作业运行时,shell自动转到后台执行,成为后台进程组。前台作业运行结束后,shell就把自己提到前台运行(如果有子进程则子进程还在,子进程不属于作业)。
用代码创建作业观察:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#define ERR_EXIT(m) \
    do\
    {\
        printf(m);\
        exit(EXIT_FAILURE);\
    }while(0)
int main()
{
    pid_t pid;
    if((pid = fork()) < 0)
        ERR_EXIT("fork");
    else if(pid == 0)
    {
        while(1)
        {
            printf("Child run, pid :%d\n", getpid());
            sleep(1);
        }
    }
    else
    {
        int i = 1;
        while(i <= 5)
        {
            printf("%dsecond, father :%d\n", i, getpid());
            i++;
            sleep(1);
        }
    }

    return 0;
}

父进程在5秒后退出,shell返回前台。而子进程依然在后台运行,用Ctrl+C不能结束子进程:
这里写图片描述

三、会话:会话(Session)是一个或多个进程组的集合。一个会话可以有一个控制终端。这通常是登录到其上的终端设备(终端登录的情况下)或伪终端设备(网络登录的情况下)。
建立与控制终端连接的会话首进程称为控制进程。一个会话中的几个进程组可被分为一个前台进程组和任意多个后台进程组。所以一个会话中应包含一个控制进程(会话首进程)、一个前台进程组合任意多个后台进程。
在shell创建3个后台进程:
这里写图片描述
这里bash为控制进程,同时也是前台作业,而三个sleep进程属于同一个进程组,是一个后台作业。这样bash进程和三个sleep进程构成了一个会话。

作业控制有关信号:
jobs:可查看当前有哪些作业。
选项:
-l:显示进程号;
-p:仅任务对应的显示进程号;
-n:显示任务状态的变化;
-r:仅输出运行状态(running)的任务;
-s:仅输出停止状态(stoped)的任务。

fg:将指定(如果后台作业只有一个不用指定)作业提至前台运行,如果作业处于停止状态,则给这个作业的每个进程发送SIGCONT信号使之运行。

bg:用于将指定作业放到后台运行,其运行效果与在指令后面加&一样。如果指定作业处于停止状态,则向作业中每个进程发送SIGCONT信号使之运行。

Ctrl+Z:向前台作业进程发送SIGTSTP信号,使前台作业停止,并以后台作业方式存在。

Ctr+C:给前台作业中的每个进程发送SIGINT信号,结束前台作业。对后台作业无效。

SIGTERM(15):给一个停止的进程发送这个信号后,这个信号并不会立即处理,而要等进程准备运行之前处理,其默认处理动作是结束进程。

创建三个后台作业:
这里写图片描述
分别用jobs的-l和-p选项列出三个作业:
这里写图片描述
将一号作业转到前台运行,然后使之停止,并转到后台:
这里写图片描述
用bg是一号作业继续运行:
这里写图片描述
用同样的方法是作业2停止,然后分别列出处于运行状态和停止状态的作业:
这里写图片描述
这里写图片描述
给作业2的某个进程发送SIGTERM信号,这个进程和作业还存在:
这里写图片描述
再次是这个作业运行后,被发送SIGTERM信号的进程被杀死了,而同一个作业中的其他进程还继续运行:
这里写图片描述

阅读更多
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/xuzhangze/article/details/79955022
个人分类: linux
上一篇进程信号的捕捉
下一篇守护进程
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭