进程间关系和守护进程
一. 進(jìn)程組/作業(yè)/會(huì)話(huà)
1.進(jìn)程組
????每一個(gè)進(jìn)程除了有一個(gè)進(jìn)程ID之外, 還屬于一個(gè)進(jìn)程組. 進(jìn)程是一個(gè)或多個(gè)進(jìn)程的集合. 通常, 它們與同一個(gè)作業(yè)向關(guān)聯(lián), 可以接收來(lái)自同一個(gè)終端下的各種命令,信號(hào). 每一個(gè)進(jìn)程組都有唯一的進(jìn)程組 ID. 每一個(gè)進(jìn)程組都可以有一個(gè)組長(zhǎng)進(jìn)程. 組長(zhǎng)進(jìn)程的標(biāo)識(shí)是, 其進(jìn)程組 ID 等于組長(zhǎng)進(jìn)程 ID. 組長(zhǎng)進(jìn)程可以創(chuàng)建一個(gè)進(jìn)程組, 也可以創(chuàng)建該進(jìn)程組中的進(jìn)程, 然后終止.只要該組中有一個(gè)進(jìn)程存在, 則該組就存在, 與該組中的組長(zhǎng)進(jìn)程是否存在沒(méi)有任何關(guān)系
2. 相關(guān)接口函數(shù)
????????????????
????其中g(shù)etpgrp 函數(shù)用來(lái)返回調(diào)用進(jìn)程的進(jìn)程組 ID, setpid 用來(lái)將 pid 進(jìn)程的進(jìn)程組 ID 設(shè)置為 pgid, 如果兩個(gè)參數(shù)值相等, 則由 pid 指定的進(jìn)程將會(huì)變成進(jìn)程組組長(zhǎng). 如果 pid 為 0, 則使用調(diào)用者的進(jìn)程 id. 另外, 如果 pgid 為 0, 則由進(jìn)程 pid 指定的進(jìn)程 id將會(huì)變成進(jìn)程組 id.一個(gè)進(jìn)程只能為自己的子進(jìn)程或者為自己設(shè)定進(jìn)程組ID, 但是當(dāng)這個(gè)函數(shù)的子進(jìn)程已經(jīng)調(diào)用了 exec 之后, 父進(jìn)程就不能再改變子進(jìn)程的組ID了
????在大多數(shù)shell下通常是調(diào)用 fork 后讓父進(jìn)程調(diào)用 setpgid , 同時(shí)也讓子進(jìn)程調(diào)用 setpgid.
????其中 ps 命令常用來(lái)顯示進(jìn)程相關(guān)信息, 其中選項(xiàng) a 表示不僅列出當(dāng)前用戶(hù)的進(jìn)程, 也列出其他所有用戶(hù)進(jìn)程, x 表示不僅列出有控制終端的進(jìn)程, 也列出沒(méi)有控制終端的進(jìn)程, j 表示列出與作業(yè)相關(guān)的信息, 同時(shí)在上圖中可以看出當(dāng)我們殺死這個(gè)進(jìn)程組中的組長(zhǎng)時(shí), 此時(shí)該組還是任然存在的(該組中的成員還依舊在). 利用 jobs 命令可以查看后臺(tái)相關(guān)進(jìn)程
3. 作業(yè)
????shell分前臺(tái)和后臺(tái)運(yùn)行的不是進(jìn)程, 而是作業(yè)或者進(jìn)程組. 一個(gè)前臺(tái)作業(yè)可以由多個(gè)進(jìn)程構(gòu)成, 一個(gè)后臺(tái)作業(yè)也可以由多個(gè)進(jìn)程組成, shell可以一次運(yùn)行一個(gè)前臺(tái)作業(yè)和任意多個(gè)后臺(tái)作業(yè), 這就叫做作業(yè)控制.
????作業(yè)和進(jìn)程組的區(qū)別: 在作業(yè)中某個(gè)進(jìn)程創(chuàng)建了一個(gè)子進(jìn)程, 該子進(jìn)程屬于該進(jìn)程組, 但是該子進(jìn)程不屬于這個(gè)作業(yè).一旦作業(yè)結(jié)束, shell就把自己提到前臺(tái), (子進(jìn)程還在, 但是子進(jìn)程不屬于改作業(yè)), 如果原來(lái)的前臺(tái)進(jìn)程還在, (如果原來(lái)的子進(jìn)程還沒(méi)有終止), 它將自動(dòng)成為一個(gè)后臺(tái)進(jìn)程. 此時(shí)我們就可以理解當(dāng)我們?cè)谇芭_(tái)起一個(gè)新作業(yè)時(shí), 此時(shí)shell無(wú)法執(zhí)行, 那是因?yàn)閟hell被放到了后臺(tái), 而當(dāng)改作業(yè)退出的時(shí)候, shell就被提到了前臺(tái).
3. 會(huì)話(huà)
????會(huì)話(huà)是一個(gè)或多個(gè)進(jìn)程組的集合, 一個(gè)會(huì)話(huà)可以有一個(gè)控制終端. 這通常是登錄到其上的終端設(shè)備或者是偽終端設(shè)備. 建立與控制終端連接的會(huì)話(huà)首進(jìn)程是控制進(jìn)程. 一個(gè)終端下的幾個(gè)進(jìn)程組可以被分為一個(gè)前臺(tái)作業(yè)以及一個(gè)或多個(gè)后臺(tái)作業(yè).所以一個(gè)會(huì)話(huà)中應(yīng)該包括一個(gè)控制進(jìn)程, 一個(gè)前臺(tái)進(jìn)程組和多個(gè)后臺(tái)進(jìn)程組
????通過(guò)上面的一些解釋, 我們可以得知, 一個(gè)作業(yè)或者一個(gè)進(jìn)程組由多個(gè)進(jìn)程組成, 而一個(gè)會(huì)話(huà)則由一個(gè)前臺(tái)進(jìn)程組和多個(gè)后臺(tái)進(jìn)程組構(gòu)成.
(1)會(huì)話(huà)相關(guān)接口
????????????????????????????????
????該函數(shù)用于建立一個(gè)新的會(huì)話(huà), 如果調(diào)用函數(shù)的進(jìn)程不是一個(gè)進(jìn)程的組長(zhǎng), 那么就建立新的會(huì)話(huà). 此時(shí)該進(jìn)程會(huì)變成新的會(huì)話(huà)首進(jìn)程, 而此時(shí)該進(jìn)程就會(huì)成為新會(huì)話(huà)中的唯一的一個(gè)進(jìn)程. 而該進(jìn)程會(huì)成為一個(gè)新進(jìn)程組長(zhǎng), 該進(jìn)程 ID 等于調(diào)用該進(jìn)程的進(jìn)程 ID. 該進(jìn)程沒(méi)有控制端, 如果在調(diào)用 setsid 前該進(jìn)程有一個(gè)控制端, 那么原有的這個(gè)控制端將會(huì)變成一個(gè)普通文件不再是控制終端
????????????????????????????????
????查看進(jìn)程的會(huì)話(huà)編號(hào)SID, 當(dāng) pid = 0 時(shí), 函數(shù)返回調(diào)用進(jìn)程會(huì)話(huà)首進(jìn)程進(jìn)程組 ID
????一個(gè)作業(yè)有多個(gè)進(jìn)程構(gòu)成, 一個(gè)會(huì)話(huà)由多個(gè)作業(yè)構(gòu)成, 其中包括一個(gè)前臺(tái)作業(yè)和多個(gè)后臺(tái)作業(yè), 建立一個(gè)會(huì)話(huà), 就是會(huì)建立一個(gè)話(huà)首進(jìn)程, 而刪除話(huà)首進(jìn)程, 該會(huì)話(huà)將會(huì)退出.
(2)相關(guān)命令
???? 1)將一個(gè)作業(yè)放到后臺(tái)去執(zhí)行時(shí), 只需在可執(zhí)行程序后面加一個(gè) & 即可. 例如 sleep 100 | sleep 200 &
???? 2)查看后臺(tái)作業(yè): jobs
???? 3) 將一個(gè)后臺(tái)作業(yè)由前臺(tái)提到后臺(tái) Ctrl + Z, bg 作業(yè)號(hào)即可
4. 作業(yè)控制相關(guān)信號(hào)
???? 后臺(tái)作業(yè)是不能讀取終端輸入的, jobs 命令可以查看后臺(tái)相關(guān)作業(yè). fg 可以將某個(gè)作業(yè)從后臺(tái)提到前臺(tái), 但是此時(shí)如果該作業(yè)是停止?fàn)顟B(tài), 則給作業(yè)發(fā)送一個(gè) SIGCONT 信號(hào)使得該作業(yè)能夠繼續(xù)運(yùn)行. bg 將某個(gè)停止的后臺(tái)作業(yè)在后臺(tái)運(yùn)行, 也需要給作業(yè)發(fā)送一個(gè) SIGCONT 信號(hào). 此時(shí)該作業(yè)就可以在后臺(tái)運(yùn)行了.后臺(tái)作業(yè)不能從終端讀取數(shù)據(jù), 但是后臺(tái)作業(yè)可以往終端寫(xiě)數(shù)據(jù)
二.守護(hù)進(jìn)程
1. 相關(guān)概念
????守護(hù)進(jìn)程也叫做精靈進(jìn)程, 是運(yùn)行在后臺(tái)的一個(gè)特殊進(jìn)程. 它獨(dú)立于控制終端, 自成進(jìn)程組, 自成會(huì)話(huà), 并且周期性地執(zhí)行某些任務(wù)或者周期性地處理某些發(fā)生的事件. Linux 下大多數(shù)的服務(wù)器就是用守護(hù)進(jìn)程來(lái)實(shí)現(xiàn)的.
???? Linux下有一些進(jìn)程沒(méi)有控制終端, 不能直接和用戶(hù)交互. 其他進(jìn)程都需要用戶(hù)登錄或運(yùn)行時(shí)創(chuàng)建, 但是守護(hù)進(jìn)程不受用戶(hù)登錄或注銷(xiāo)的影響, 它會(huì)一直運(yùn)行.
????通過(guò) ps 命令查看系統(tǒng)中的進(jìn)程, 其中 PPID 是父進(jìn)程編號(hào), PID 是當(dāng)前進(jìn)程編號(hào), PGID 是進(jìn)程組ID, SID 是會(huì)話(huà) ID, TTY 表示終端名稱(chēng), TPGID 表示會(huì)話(huà)組ID, STAT 表示進(jìn)程狀態(tài), UID表示用戶(hù)ID, COMMAND 表示命令字符串可以看到 凡是 TPGID 為 -1 的都是守護(hù)進(jìn)程, COMMAND 用 [] 括起來(lái)的都是內(nèi)核線(xiàn)程, 這些線(xiàn)程都是在內(nèi)核中創(chuàng)建, 沒(méi)有用戶(hù)代碼, 沒(méi)有程序文件以及命令行, 通常以 k 開(kāi)頭. 守護(hù)進(jìn)程一般以 d 結(jié)尾的名字
2. 守護(hù)進(jìn)程的創(chuàng)建
#include<unitd.h> pid_t setsid(); 調(diào)用成功時(shí)返回創(chuàng)建的會(huì)話(huà)ID, 失敗時(shí)返回 -1????該函數(shù)在調(diào)用的時(shí)候必須保證調(diào)用的進(jìn)程不能是進(jìn)程組組長(zhǎng), 為了保證該點(diǎn), 就先 fork 然后再讓子進(jìn)程去執(zhí)行 setsid 即可. 其中在創(chuàng)建會(huì)話(huà)時(shí), 子進(jìn)程就會(huì)自成組長(zhǎng), 即子進(jìn)程的 id 就會(huì)成為其組長(zhǎng)的id, 并且該進(jìn)程也會(huì)自成會(huì)話(huà), 即會(huì)話(huà) ID就是該進(jìn)程的 ID, 并且如果當(dāng)前進(jìn)程有一個(gè)會(huì)話(huà)終端的時(shí)候, 它將會(huì)失去原有的會(huì)話(huà)終端, 即原來(lái)的會(huì)話(huà)終端還是打開(kāi)的, 仍然可以讀寫(xiě), 但是將會(huì)變成一個(gè)普通文件, 不再是控制終端了.
#include<stdio.h> #include<unistd.h> #include<signal.h> #include<fcntl.h> #include<sys/stat.h> #include<stdlib.h>void mydaemon() {int fd0;pid_t id;struct sigaction sa;//1. 屏蔽umaskumask(0);id = fork();if(id < 0){perror("fork");exit(1);}//2. fork 父進(jìn)程退出, 子進(jìn)程運(yùn)行if(id > 0){exit(0);}if(setsid() < 0){perror("setsid");exit(1);}//3. 初始化sasigemptyset(&sa.sa_mask);sa.sa_handler = SIG_IGN;sa.sa_flags = 0;//4. 對(duì)SIGCHLD信號(hào)忽略, 防止產(chǎn)生僵尸進(jìn)程if(sigaction(SIGCHLD, &sa, NULL) < 0){perror("sigaction");exit(1);}fd0 = open("/dev/null", O_RDWR);close(0);dup2(fd0, 1);dup2(fd0, 2); }int main() {mydaemon();while(1){sleep(1);}return 0; }????????
????關(guān)閉當(dāng)前終端, 打開(kāi)另外一個(gè)終端時(shí), 繼續(xù)查看, 會(huì)發(fā)現(xiàn)原來(lái)的會(huì)話(huà)還存在, 于是我們可以得出結(jié)論, 守護(hù)進(jìn)程單獨(dú)成組, 單獨(dú)成回話(huà), 不受控制終端控制
????????
總結(jié)
以上是生活随笔為你收集整理的进程间关系和守护进程的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 有输卵管堵塞该怎么办较优
- 下一篇: 网络相关基础概念