歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux綜合 >> 學習Linux >> 終端&作業控制&會話啟動過程,超級終端

終端&作業控制&會話啟動過程,超級終端

日期:2017/3/6 9:30:01   编辑:學習Linux

終端&作業控制&會話啟動過程,超級終端


終端&作業控制&會話啟動過程,超級終端


進程組

每個進程除了有個進程id外,還屬於一個進程組。進程組是一個或者多個進程的集合。通常他們與同一個作業相關聯,可以接受來自同一終端的信號。進程組id等於其進程組長id。進程組的終止與進程組長是否存在無關,只要有一個成員進程存在,那麼這個進程組就存在。

作業

shell分前後台進行控制的不是進程而是作業或者進程組。一個前台作業可以由多個進程組成,一個後台作業也可以由多個進程組成。shell可以運行一個前台作業和多個後台作業,這稱為作業控制。

作業與進程組的區別:如果一個作業中的某個進程創建了一個子進程,那麼這個子進程不屬於作業,但屬於進程組。

會話

會話是一個或者多個進程組的集合。

一個會話可以有一個控制終端。建立與控制終端連接的會話首進程被稱為控制進程。

注:通過管道方式實現一個作業任務。

前兩行:對比可以看出,兩個sleep命令的PPID(父進程id:bash),PGID(進程組ID),SID(會話ID),TTY(終端)都是相同的。

    PID是不同的,他們是一個進程組中的兩個不同進程。

將之與第三行對比,發現,各個項都是不同的,特別是SID,TTY,TPGID(top PGID(前台進程組ID))都是不同的。

ps -e 或 ps -o pid,ppid,session,tpgid, comm (其中session顯示的sessionid, tpgid顯示前台進程組id, comm顯示命令名稱)

同時,我們可以驗證,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;
}

現在我們來看終端登錄的過程:

1、系統啟動時,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這個命令,所以 我們從終端退出登錄後會再次提示示輸入入帳號。

2、getty根據命令行行參數打開終端設備作為它的控制終端,把文文件描述符0、1、2都指向控制終 端,然後提示示用用戶輸入入帳號。用用戶輸入入帳號之後,getty的任務就完成了,它再執行行login程序:
execle("/bin/login", "login", "-p", username, NULL, envp);

3、如果密碼不正確,login進程終止止,init會重新fork/exec一一個getty進程。如果密碼正確,login程 序設置一一些環境變量,設置當前工工作目目錄為該用用戶的主目目錄,然後執行行Shell:

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

從getty開始exec到login,再exec到bash,其實都是同一一個進程,因此控制終 端沒變,文文件描述符0、1、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 禁止後台進程寫。然後才能成功

http://xxxxxx/Linuxjc/1143806.html TechArticle

Copyright © Linux教程網 All Rights Reserved