1. 程式人生 > >【Linux】程序間的關係以及終端的概念

【Linux】程序間的關係以及終端的概念

程序間關係

程序組

每個程序都有自己的程序ID,除此之外,每個程序也都屬於一個程序組。

程序組是一個程序或者多個程序的集合。

通常他們和同一個作業有聯絡,可以接受來自同一個終端的訊號。

每一個程序組都有一個組ID,這個ID就是該程序組組長的程序ID

組長程序可以建立一個程序組,並建立該組中的程序。

當一個程序組中的所有程序死亡時,該程序組才會終止。

當一個程序組的組長死亡時,只要有其他程序存在,則該程序組存在。並且組ID仍是已故的組長程序ID。

作業

Shell通過前臺和後臺來分別控制前臺作業和後臺作業。這稱為作業控制

Shell可以同時執行一個前臺作業和多個後臺作業。

一個作業可以由多個程序構成

作業和程序組的區別

當一個作業H中的某個程序A建立了一個子程序後B,這個程序B不屬於作業H;然而程序A和程序B都屬於同一個程序組

當前臺作業執行結束後,Shell就把自己提到前臺。如果前臺作業的某個子程序還沒有終止,則它自動變為後臺程序

一般情況下,作業和程序組可以不做區分,但是我們要知道他們的不同之處是什麼。

檢視後臺作業

jobs 

將前臺作業提至後臺

bg 1(作業號) 先要contrl C終止後臺作業 

將後臺作業提至前臺

fg 1(作業號)

區別驗證

fork出一個子程序後,如果將父程序退出,則前臺作業結束

子程序會以後臺程序的身份繼續執行

此時,我們用Ctrl+C無法終止該子程序(因為CTRL+C只可以終止前臺作業)

程式碼

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

int main()
{
	pid_t pid = fork();//建立子程序
	
	while(1)
	{
		if(pid < 0)
		{
			perror("fork");
			return -1;
		}
		else if(pid == 0)
		{
			printf("子程序在執行\n");
			sleep(1);
		}
		else
		{
			printf("父程序結束\n");
			exit(0);
		}
	}
	return 0;
}
 

執行結果


會話

會話(Session)是一個或多個程序組的集合。

一個會話可以有一個控制終端。

這通常是登陸到其上的終端裝置(在終端登陸情況下)或偽終端裝置(在網路登陸情況下)。

建立與控制終端連線的會話首程序被稱為控制程序。 

一個會話中的幾個程序組可被分為一個前臺程序組以及一個或多個後臺程序組。

所以一個會話中,應該包括控制程序(會話首程序),一個前臺程序組和任意後臺程序組。

新開啟一個終端即新建立一個會話的過程。關閉一個終端,即關閉一次會話 ,其中所有的作業,程序組都不存在了。

proc1 | proc2 | proc3 &
proc4 | proc5

其中proc1與proc2和proc3屬於同一個後臺程序組,proc4和proc5屬於同一個前臺程序組

Shell本身屬於一個單獨的程序組。

這些程序組的控制終端相同,它們同屬於一個會話,當用戶在控制終端輸入特殊的控制鍵(如Ctrl+C,產生SIGINT,Ctrk+,產生SIGQUIT,Ctrl+Z,
產生SIGTSTP),核心傳送相應的訊號給前臺程序組中的所有程序。

終端

終端的基本概念

在UNIX系統中,使用者通過終端登入系統後得到一個Shell程序,這個終端成為Shell程序的控制終端 (Controlling Terminal)

控制終端是儲存在PCB中的資訊,而我們知道fork會複製PCB中的資訊,因此由Shell程序啟動的其它程序的控制終端也是這個終端。

預設情況 下(沒有重定向)

每個程序的標準輸入、標準輸出和標準錯誤輸出都指向控制終端,程序從標準輸入讀也就是讀使用者的鍵盤輸入,程序往標準輸出或標準錯誤輸出寫也就是輸出到顯示器上。

此外在控制終端輸入一些特殊的控制鍵可以給前臺程序發訊號,例如Ctrl-C表示SIGINT,Ctrl-\表示SIGQUIT。

如何檢視終端

每個程序都可以通過一個特殊的裝置檔案/dev/tty訪問它的控制終端。 ttyname函式可以由檔案描述符查出對應的檔名,該檔案描述符必須指向一個終端裝置而不 能是任意檔案。

在一個終端上開啟


在另一個終端上開啟