1. 補(bǔ)充
1.1 查看
為了觀察進(jìn)程,我們以在命令提示符處,運(yùn)行 sleep 命令為例。
ps axj | head -1 && ps axj | grep sleep | grep -v grep
-
得到的信息:
-
PPID
:父進(jìn)程 ID -
PID
:進(jìn)程 ID -
PGID
:進(jìn)程組 -
SID
:會(huì)話 ID -
TTY
:進(jìn)程關(guān)聯(lián)的終端
每登錄一次,都是一個(gè)新的會(huì)話,即每個(gè)會(huì)話關(guān)聯(lián)一個(gè)終端文件,進(jìn)程組的名稱是進(jìn)程組中第一個(gè)進(jìn)程的 PID。
- 進(jìn)程組,分為前臺任務(wù)和后臺任務(wù)
- 在會(huì)話中,只能有一個(gè)前臺任務(wù)在運(yùn)行
(解釋了我們在命令行啟動(dòng)一個(gè)進(jìn)程的時(shí)候,bash 就無法工作了的原因) - 每次登錄就是創(chuàng)建一個(gè)新的會(huì)話、bash 任務(wù);啟動(dòng)進(jìn)程,就是在當(dāng)前會(huì)話中創(chuàng)建一個(gè)后臺任務(wù);退出會(huì)話,會(huì)影響會(huì)話內(nèi)部的所有任務(wù)
- 一般網(wǎng)絡(luò)服務(wù)器,為了不受到用戶的登陸注銷的影響,網(wǎng)絡(luò)服務(wù)器會(huì)以 守護(hù)進(jìn)程 的方式運(yùn)行!
1.2 控制進(jìn)程組的方式
jobs
:查看自己會(huì)話中后臺運(yùn)行的進(jìn)程fg [任務(wù)號]
:將相應(yīng)進(jìn)程提到前臺ctrl + Z
:將前臺運(yùn)行的進(jìn)程暫停,并放入后臺bg [任務(wù)號]
:運(yùn)行后臺暫停的進(jìn)程
2. 創(chuàng)建守護(hù)進(jìn)程
為了不受用戶影響,網(wǎng)絡(luò)服務(wù)器會(huì)將其進(jìn)程單獨(dú)拎出來,使用新的會(huì)話和進(jìn)程組,為此稱守護(hù)進(jìn)程
step1. 忽略信號
signal(SIGPIPE, SIG_IGN);
signal(SIGCHLD, SIG_IGN);
// ...
step2. 讓自己不是組長
要設(shè)置新的會(huì)話和進(jìn)程組 ID,需要使用 setsid 接口,而每個(gè)進(jìn)程組的組長(進(jìn)程組號同自己 PID 的進(jìn)程)是不能舍自己進(jìn)程組不顧的,即使用 setsid 創(chuàng)建新組,必須不能是組長。
if (fork() > 0) exit(0);
-
fork出多進(jìn)程,讓父進(jìn)程退掉,子進(jìn)程繼續(xù)跑,就相當(dāng)于讓出了組長。
-
本質(zhì)上,守護(hù)進(jìn)程就是 孤兒進(jìn)程 的一種
step3. setsid 函數(shù):給調(diào)用函數(shù)設(shè)置新的會(huì)話和進(jìn)程組 ID
#include <unistd.h> pid_t setsid(void);
返回值:
- 成功返回新的進(jìn)程組 ID,失敗返回 -1,并設(shè)置錯(cuò)誤碼
注意:組長是不能使用該接口的
step4. chdir 函數(shù):可以改變守護(hù)進(jìn)程的工作路徑
非必要步驟
#include <unistd.h> int chdir(const char *path);
返回值:
- 成功返回 0,失敗返回 -1,并設(shè)置錯(cuò)誤碼
step5. 處理文件描述符 0、1、2
這里的處理是將這些文件重新向到 /dev/null
中,目的是切斷新會(huì)話和鍵盤等的聯(lián)系。
這里的 /dev/null 是一個(gè)字符設(shè)備,傳進(jìn)的數(shù)據(jù)都會(huì)被直接丟棄。文章來源:http://www.zghlxwxcb.cn/news/detail-707822.html
守護(hù)進(jìn)程類樣例
#include <cstdlib>
#include <unistd.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
void Daemon()
{
// 1. 忽略信號
signal(SIGPIPE, SIG_IGN);
signal(SIGCHLD, SIG_IGN);
// 2. 讓自己不要成為組長
if (fork() > 0)
exit(0);
// 3. 新建會(huì)話,自己成為會(huì)話的話首進(jìn)程
pid_t ret = setsid();
if ((int)ret == -1)
{
// 日志或打印
exit(1);
}
// 4. 可選:可以更改守護(hù)進(jìn)程的工作路徑
// chdir("/")
// 5. 處理后續(xù)的對于0,1,2的問題
int fd = open("/dev/null", O_RDWR);
if (fd < 0)
{
// 日志或打印
exit(2);
}
dup2(fd, 0);
dup2(fd, 1);
dup2(fd, 2);
close(fd);
}
??如果本文對你有些幫助,請給個(gè)贊或收藏,你的支持是對作者大大莫大的鼓勵(lì)?。?????) 歡迎評論留言~~文章來源地址http://www.zghlxwxcb.cn/news/detail-707822.html
到了這里,關(guān)于【Linux】進(jìn)程篇(補(bǔ)):守護(hù)進(jìn)程的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!