Linux之守護進程詳解
一、守護進程的概念
我們在前面的博文《進程信號的產(chǎn)生》中提到過前臺進程和后臺進程的概念,它們之間的區(qū)別就是是否獲得鍵盤文件,擁有鍵盤輸入的就是前臺進程,后臺進程獲取不到鍵盤文件
守護進程是 Linux 系統(tǒng)中運行在后臺的特殊進程,具有無終端依賴、長期運行、權限分離等特點,通常用于實現(xiàn)系統(tǒng)服務、網(wǎng)絡服務等功能,進行守護進程化的進程就是將終端關閉也不會殺死,只要服務器一直運行,它就可以一直運行,但可以通過kill
命令殺死
二、調(diào)用接口
1、創(chuàng)建新會話
#include <unistd.h> pid_t setsid(void);
返回值:成功返回新會話id,失敗返回-1
2、守護進程
#include <unistd.h> int daemon(int nochdir, int noclose);
返回值:成功返回0,失敗返回-1
nochdir
:如果該參數(shù)的值為 0,daemon
函數(shù)會將當前工作目錄更改為根目錄(/),如果為非 0 值,則不更改當前工作目錄noclose
:如果該參數(shù)的值為 0,daemon 函數(shù)會將標準輸入、標準輸出和標準錯誤輸出重定向到/dev/null
,如果為非 0 值,則不進行重定向
三、進程屬性信息
1. PPID(Parent Process ID)
- 全稱:父進程ID
- 含義:當前進程的父進程的唯一標識符
- 作用:用于跟蹤進程間的父子關系(例如,通過
fork()
創(chuàng)建的子進程會繼承父進程的PPID)
2. PID(Process ID)
- 全稱:進程ID
- 含義:操作系統(tǒng)分配給每個進程的唯一數(shù)字標識符(范圍通常為1~32768)
- 作用:用于區(qū)分和管理系統(tǒng)中的不同進程(例如,通過
kill
命令終止進程)
3. PGID(Process Group ID)
- 全稱:進程組ID
- 含義:進程所屬的進程組的ID,進程組是一個或多個相關進程的集合,一個任務對應一個進程組
- 作用:便于批量管理相關進程(如停止或恢復整個進程組)
4. SID(Session ID)
- 全稱:會話ID
- 含義:進程所屬的會話的ID,會話由一個或多個進程組組成,通常由登錄
shell
創(chuàng)建,實際上是bash
的id
- 作用:管理終端會話中的所有進程(例如,當用戶注銷時,整個會話的進程會被終止)
5. TTY(Teletypewriter)
- 全稱:終端設備
- 含義:進程關聯(lián)的終端設備(如
pts/0
表示偽終端),若顯示為?
,表示進程無控制終端 - 作用:區(qū)分進程是否在終端中運行(如后臺服務通常無終端)
6. TPGID(Foreground Process Group ID)
- 全稱:前臺進程組ID
- 含義:當前在終端前臺運行的進程組的ID
- 作用:終端輸入/輸出會被分配給前臺進程組(例如,按
Ctrl+C
會中斷前臺進程)
7. STAT(Process Status)
全稱:進程狀態(tài)
含義:進程的當前狀態(tài),常見狀態(tài)碼包括:
R
(運行中)S
(睡眠中)D
(不可中斷睡眠)T
(停止)Z
(僵尸進程)
作用:快速判斷進程的運行狀態(tài)(例如,Z
表示進程已終止但未被父進程回收)
8. UID(User ID)
- 全稱:用戶ID
- 含義:啟動進程的用戶的唯一標識符(如
root
的UID為0) - 作用:用于權限控制(例如,普通用戶無法修改
root
進程)
9. TIME
- 全稱:CPU時間
- 含義:進程自啟動以來累計使用的CPU時間(格式為
HH:MM:SS
) - 作用:衡量進程對CPU資源的占用情況
10. COMMAND
- 全稱:命令名稱
- 含義:啟動進程的命令或程序名稱(如
bash
、nginx
) - 作用:快速識別進程的功能(例如,通過
COMMAND
列判斷是否為惡意程序)
同一個session
內(nèi)啟動的sid
都一樣
同一PGID
的,即一個組內(nèi)的,PID
與PGID
相同的被稱為組長
四、深入理解守護進程
1、實現(xiàn)過程
首先創(chuàng)建子進程然后退出父進程,使子進程在后臺運行,然后創(chuàng)建新會話,脫離掉原會話和控制終端,保證進程不受終端信號影響,然后再重定向標準輸入輸出,確保守護進程不與終端交互,然后變更工作目錄,忽略掉子進程退出信號和終端停止信號,所以守護進程本質(zhì)上是一個孤兒進程
2、實例
#include <unistd.h> #include <sys/types.h> #include <fcntl.h> #include <syslog.h> void daemonize() { // 創(chuàng)建子進程并退出父進程,子進程成為孤兒進程 pid_t pid = fork(); if (pid < 0) exit(EXIT_FAILURE); if (pid > 0) exit(EXIT_SUCCESS); // 創(chuàng)建新會話,調(diào)用該函數(shù)的進程會成為新會話的會話首進程、新進程組的組長進程 //并且會脫離原有的控制終端 if (setsid() == -1) exit(EXIT_FAILURE); // 重定向標準輸入輸出 close(STDIN_FILENO); close(STDOUT_FILENO); close(STDERR_FILENO); int fd = open("/dev/null", O_RDWR); dup2(fd, STDIN_FILENO); dup2(fd, STDOUT_FILENO); dup2(fd, STDERR_FILENO); // 允許所有權限 umask(0); // 變更工作目錄 chdir("/"); // 忽略子進程狀態(tài)改變時發(fā)送給父進程的信號 signal(SIGCHLD, SIG_IGN); } int main() { daemonize(); while (1) { sleep(3600); // 模擬工作 } return 0; }
上面的過程,可以被函數(shù)daemon
函數(shù)替換
#include <unistd.h> #include <syslog.h> int main() { // 使用 daemon 函數(shù)將當前進程轉(zhuǎn)換為守護進程 // 第一個參數(shù) 0 表示將工作目錄更改為根目錄 // 第二個參數(shù) 0 表示將標準輸入、標準輸出和標準錯誤輸出重定向到 /dev/null if (daemon(0, 0) == -1) { perror("daemon"); return 1; } // 模擬守護進程持續(xù)工作 while (1) { // 睡眠 3600 秒(1 小時) sleep(3600); } return 0; }
總結
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關文章
linux系統(tǒng)下oracle11gR2靜默安裝的經(jīng)驗分享
這篇文章主要介紹了linux系統(tǒng)下oracle11gR2靜默安裝的經(jīng)驗, 所有操作無需使用圖形界面. 靜默安裝能減少安裝出錯的可能性, 也能大大加快安裝速度。有需要的朋友可以參考借鑒,下面來一起看看吧。2017-01-01Ubuntu下Sublime Text無法輸入中文最簡單的解決方案
今天小編就為大家分享一篇關于Ubuntu下Sublime Text無法輸入中文最簡單的解決方案,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧2018-10-10Linux使用tracepath進行網(wǎng)絡診斷分析
tracepath?命令是?Linux?中的一個網(wǎng)絡診斷工具,類似于?traceroute,下面小編來為大家介紹一下如何使用tracepath進行網(wǎng)絡診斷分析吧2025-02-02Linux虛擬機ipaddr/ifconfig不顯示IP的解決方案(親測有效)
有時候經(jīng)常會出現(xiàn)之前明明好的,但是換了個網(wǎng)絡就查不到ip了,由于不知道原因,有的人會選擇重裝虛擬機,還有的人開始崩潰,本篇文章將徹底解決該問題的出現(xiàn),需要的朋友可以參考下2023-09-09