終端&做業控制&會話啓動過程

進程組

每一個進程除了有個進程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 禁止後臺進程寫。而後才能成功

相關文章
相關標籤/搜索