终端&做业控制&会话启动过程

进程组

每一个进程除了有个进程id外,还属于一个进程组。进程组是一个或者多个进程的集合。一般他们与同一个做业相关联,能够接受来自同一终端的信号。进程组id等于其进程组长id。进程组的终止与进程组长是否存在无关,只要有一个成员进程存在,那么这个进程组就存在。linux

做业

shell分先后台进行控制的不是进程而是做业或者进程组。一个前台做业能够由多个进程组成,一个后台做业也能够由多个进程组成。shell能够运行一个前台做业和多个后台做业,这称为做业控制。shell

做业与进程组的区别:若是一个做业中的某个进程建立了一个子进程,那么这个子进程不属于做业,但属于进程组。bash

会话

会话是一个或者多个进程组的集合。session

一个会话能够有一个控制终端。创建与控制终端链接的会话首进程被称为控制进程。spa

注:经过管道方式实现一个做业任务。命令行

前两行:对比能够看出,两个sleep命令的PPID(父进程id:bash),PGID(进程组ID),SID(会话ID),TTY(终端)都是相同的。code

    PID是不一样的,他们是一个进程组中的两个不一样进程。blog

将之与第三行对比,发现,各个项都是不一样的,特别是SID,TTY,TPGID(top PGID(前台进程组ID))都是不一样的。进程

ps -e 或 ps -o pid,ppid,session,tpgid, comm (其中session显示的sessionid, tpgid显示前台进程组id, comm显示命令名称)get

同时,咱们能够验证,SID会话ID是由每一个终端进行肯定的。

由这个图咱们更能够清晰的理解到,对于每个连续的命令执行流,其进程组/做业id是相同的。会话id则是终端相关的。

 

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

int main(int argc, char const *argv[])
{
    printf("fd: %d -> %s\n",0,ttyname(0) );
    printf("fd: %d -> %s\n",1,ttyname(1) );
    printf("fd: %d -> %s\n",2,ttyname(2) );
    return 0;
}

如今咱们来看终端登陆的过程:

一、系统启动时,init进程根据配置文件/etc/inittab肯定须要打开哪些终端。例如配置文件中有
这样一行:
1:2345:respawn:/sbin/getty 9600 tty1

和/etc/passwd相似,每一个字段用用:号隔开。开头的1是这一一行行配置的id,一般要和tty的后缀一一致,配置tty2的那一一行行id就应该是2。第二二个字段2345表示示运行行级别2~5都执行行这个配置。最后一个字 段/sbin/getty 9600 tty1是init进程要fork/exec的命令,打开终端/dev/tty1,波特率 是9600(波特率只对串又口口和Modem终端有意义),而后提示示用用户输入入账号。中间的respawn字段表示示init进程会监视getty进程的运行行状态,一一旦该进程终止止,init会再次fork/exec这个命令,因此 咱们从终端退出登陆后会再次提示示输入入账号。

二、getty根据命令行行参数打开终端设备做为它的控制终端,把文文件描述符0、一、2都指向控制终 端,而后提示示用用户输入入账号。用用户输入入账号以后,getty的任务就完成了,它再执行行login程序:
execle("/bin/login", "login", "-p", username, NULL, envp);

三、若是密码不正确,login进程终止止,init会从新fork/exec一一个getty进程。若是密码正确,login程 序设置一一些环境变量,设置当前工工做目目录为该用用户的主目目录,而后执行行Shell:

execl("/bin/bash", "-bash", NULL);

从getty开始exec到login,再exec到bash,其实都是同一一个进程,所以控制终 端没变,文文件描述符0、一、2也仍然指向控制终端。因为fork会复制PCB信息,因此由Shell启动的 其它进程也都是如此。

从会话角度讲 终端开启过程是:

1。getty或者telnetd调用setsid,设置会话id,在这个id的基础上开启终端,创建会话。同时建立一个进程组。且该进程是此终端下全部会话的控制终端。

2。登陆过程当中,进行exec替换。变为login,而后变为shell

3。当shell调用fork建立子进程进行工做时,调用setpgid将做业中的某个进程设置伪新的组进程,造成本会话内的一个做业流。

注:在做业中,若是某个进程建立新的子进程了,该子进程并不会做为做业内容而被等待。当真是做业完成时,做业就会退出。(进程组和做业的区别)。

关于做业的命令:

jobs查看当前系统执行做业

process & 将process做为后台做业执行。

bg 将做业改成后台执行

fg 将做业改成前台执行

参数的话, %1 表示做业号为1

lang@liang:~/linux/thread$ cat fsdf &
[2] 6470
lang@liang:~/linux/thread$ fsdf

给一个须要写入终端的命令设置后台执行时,并不能成功。

这时咱们须要设置stty tostop 禁止后台进程写。而后才能成功

相关文章
相关标签/搜索