linux程序管理總結

2021-09-19 18:58:26 字數 3662 閱讀 2699

linux程序管理總結

目錄一、程序相關的概念

二、關閉會話時子程序程序被殺死

三、nohup的原理

四、setsid原理

五、daemon &和守護程序的區別

六、服務程序為什麼要fork兩次

七、systemd管理daemon

八、殭屍程序

九、程序名字和啟動時指定程序名字

十、source command和./command 和exec命令的區別

一、程序相關的概念

程序需要了解 程序,父程序,程序組,會話和控制終端的相關概念。

程序和父程序:每個程序都有父程序,而所有的程序以init程序為根,形成乙個樹狀結構

程序組:每個程序都會屬於乙個程序組(process group),每個程序組中可以包含多個程序。程序組會有乙個程序組領導程序 (process group leader),領導程序的pid成為程序組的id (process group id, pgid),以識別程序組。

kill給組傳送訊號程序組號前加負號如:kill -9 -2189

會話:乙個或是多個程序組集合。 程序可以通過呼叫 pid_t setsid(); 來建立乙個新會話,如果呼叫此函式的程序不是程序組長,就會建立乙個新的會話,那麼此時會:

該程序稱為會話首程序 (session leader)

該程序稱為程序組組長

該程序沒有控制終端,即使之前有控制終端這種聯絡也會斷掉

可以使用第三個特性來建立 daemon 程序。 呼叫 getsid 可以獲得會話首程序程序組 pid,也就是會話首程序程序 id。

控制終端:

乙個會話持有乙個控制終端 (controlling terminal),可以是終端裝置也可以是偽終端

建立與控制終端連線的會話首程序被稱為控制程序 (controlling process)

乙個會話有多個程序組,允許存在多個後台程序組 (backgroup process group) 和乙個前台程序組 (foregroup process group)

鍵入終端的中斷鍵 (ctrl+c) 會傳送中斷訊號給前台程序組所有程序

鍵入終端的退出鍵 (ctrl+) 會傳送退出訊號給前台程序組所有程序

終端或是網路斷開會將結束通話訊號傳送給會話首程序

可以看到執行ps -fj結果如下:

uid pid ppid pgid sid c stime tty time cmd

chen 36829 36825 36829 36829 0 10:56 pts/0 00:00:00 -bash

chen 37247 36829 37247 36829 0 10:57 pts/0 00:00:00 vim

chen 90490 36829 90490 36829 0 11:57 pts/0 00:00:00 ps -fj

其中pid就是程序id,ppid是父程序id,pgid為程序組id,sid為會話id

二、關閉會話時子程序程序被殺死

終端在關閉時會傳送sighup訊號給session leader,此處就是bash程序,bash收到後向session內的所有程序傳送sighup然後退出。

sighup訊號如果為註冊處理函式預設行為就是退出。所以會話退出時子程序都被殺死。

解決方案:

關鍵**:

// 註冊處理函式

signal (sighup, sig_ign);

char **cmd = ar** + optind;

//執行實際的**

execvp (*cmd, cmd);

四、setsid原理

fork程序之後的子程序共享父程序的很多東西,並且會話組長就是父程序的會長組長,所以會收到來自父程序會話組長的訊號。

setsid用餘新建乙個會話,呼叫這個函式之後會當當前程序成為程序組組長和會話組組長,那麼原來的會話產生的訊號便不會傳送到這個程序,從而不會受影響。

五、daemon &和守護程序的區別

六、服務程序為什麼要fork兩次

首先說明兩次不是必須的,有很多程式都採用了一次fork。

第一次:為了呼叫setsid,這也解釋了為什麼呼叫setsid之前需要先fork的原因:

linux規定呼叫這個函式之前,當前程序不允許是session leader。程序組leader是該程序組的第乙個程序,fork出來的程序必定不是第乙個,所以可以呼叫setsid。另外父程序一般直接退出,可以讓shell收到程序結束的通知繼續執行,而不是等待他結束。

第二次:為了限制程序開啟控制終端,只有會話組長能開啟控制終端(非必須,相當於加了個限制條件daemon不需要開啟終端)

七、systemd管理daemon

現在很多的linux發行版都採用systemd來代替原來的init程式,systemd提供了很優秀的程序管理功能,我們需要註冊服務時可以利用systemd功能,可以參看鳥哥的systemd介紹。

另外補充點核心程序和systemd程序:

0號程序為核心程序,1號為systemd程序,其他還有些核心程序在ps命令檢視時以包裹。具體關係見:linux pid 1 和 systemd

八、殭屍程序

這個定義摘抄自維基百科:在類unix系統中,殭屍程序是指完成執行(通過exit系統呼叫,或執行時發生致命錯誤或收到終止訊號所致)但在作業系統的程序表中仍然有乙個表項(程序控制塊pcb),處於"終止狀態"的程序。這發生於子程序需要保留表項以允許其父程序讀取子程序的exit status:一旦退出態通過wait系統呼叫讀取,殭屍程序條目就從程序表中刪除,稱之為"**(reaped)"。

九、程序名字和啟動時指定程序名字

kill,ps,top,pstree這些命令都比較熟悉就不再提了。

至於還有一組命令則不是通過程序號而是通過程序名字來操作程序,pkill和killall一樣都是通過名字來殺死程序,而pgrep是通過名字來尋找程序。

他們的原理都是通過查詢/proc這個記憶體檔案系統。

在啟動的時候可以通過exec命令重新命名:

bash -c "exec -a myname sleep 500 &"

你可以通過ps -ef|grep myname來檢視程序的詳細資訊

十、source command和./command 和exec命令的區別

通常執行指令碼有三種方式

./command(同sh command)

source command(同. command)

exec command

簡單說明下上面三種方式:

第一種其實就是對應了linux的fork系統呼叫,在執行command時候,command是在子程序中執行的,當前shell等待直到子程序的command執行完畢在返回到當前shell。第二種則是直接在當前的程序中直接執行,執行完繼續接受使用者輸入。第三種則對應了linux的exec系統呼叫,當前程序的執行流程會轉向command,command是在當前程序直接執行,但是執行完之後便會直接退出。

所以我們一般用的是第一和第二兩種,這種的主要區別就是開不開新的程序(開程序是要一定開銷的),另外因為第二種是在當前程序執行的,所以如果在command中設定了變數,那麼相當於在當前程序中設定了變數,所以我們一般是用第一種去執行避免當前程序的變數被汙染。

思考:現在加入你在終端已經執行了乙個非常耗時的任務,你按ctrl+z放入了後台,然後利用bg開始任務,因為終端斷開就會收到sighup訊號,有沒有辦法忽略這個訊號或者終端斷開不收到這個訊號?

遺留:程序除錯工具:ltrace strace ftrace

總結 程序管理

程序管理主要有三個部分 程序建立和退出 程序排程 程序間通訊。首先,什麼是程序?程序就是執行著的乙個程式的例項。乙個執行中的程式包含執行狀態 屬性 位址空間等資訊,作業系統把這些東西整合起來看作程序,統一管理。程序建立 對於每個程序,核心都會為這個程序生成 乙個程序描述符 task struct 分...

LINUX程序管理

1.程序是什麼?乙個程序就是出於執行期的程式,包括 可執行程式 段 開啟的檔案,掛起的訊號,核心內部資料,處理器狀態,位址空間,乙個或多個執行執行緒,當然還包括用來存放全域性變數的資料段,等等.2.什麼是執行緒?它和程序的關係是什麼樣的?執行緒在linux中具體是怎麼樣實現的?是在程序中活動的物件,...

linux程序管理

程序的監控 使用ps aux 檢視當前所有程序。可以使用top檢視當前程序自動更新列表,在top中m 按記憶體大小排列,p 按cpu佔用率排列 終止和管理程序 程序之間通過訊號來進行通訊 top和kill都用於向程序傳送訊號。kill l顯示訊號編號表。kill 9 pid kill pid 向pi...