時間:2026-02-12 來源:成都百營鋼鐵有限公司
守護進程是什么?可能很多伙伴對于守護進程都不怎么了解吧?守護進程是操作系統(tǒng)后臺的一種特殊進程,像Linux系統(tǒng)的大多數(shù)服務(wù)器都是通過守護進程實現(xiàn)的。今天小編就來給大家科普一下什么是守護進程以及l(fā)inux系統(tǒng)如何創(chuàng)建守護進程。

一、守護進程是什么?
Linux Daemon(守護進程)是運行在后臺的一種特殊進程。它獨立于控制終端并且周期性地執(zhí)行某種任務(wù)或等待處理某些發(fā)生的事件。它不需要用戶輸入就能運行而且提供某種服務(wù),不是對整個系統(tǒng)就是對某個用戶程序提供服務(wù)。Linux系統(tǒng)的大多數(shù)服務(wù)器就是通過守護進程實現(xiàn)的。常見的守護進程包括系統(tǒng)日志進程syslogd、 web服務(wù)器httpd、郵件服務(wù)器sendmail和數(shù)據(jù)庫服務(wù)器mysqld等。
守護進程一般在系統(tǒng)啟動時開始運行,除非強行終止,否則直到系統(tǒng)關(guān)機都保持運行。守護進程經(jīng)常以超級用戶(root)權(quán)限運行,因為它們要使用特殊的端口(1-1024)或訪問某些特殊的資源。
一個守護進程的父進程是init進程,因為它真正的父進程在fork出子進程后就先于子進程exit退出了,所以它是一個由init繼承的孤兒進程。守護進程是非交互式程序,沒有控制終端,所以任何輸出,無論是向標(biāo)準輸出設(shè)備stdout還是標(biāo)準出錯設(shè)備stderr的輸出都需要特殊處理。
守護進程的名稱通常以d結(jié)尾,比如sshd、xinetd、crond等
二、創(chuàng)建守護進程的步驟
首先我們要了解一些基本概念:
1、進程組 :
每個進程也屬于一個進程組
每個進程主都有一個進程組號,該號等于該進程組組長的PID號 。
一個進程只能為它自己或子進程設(shè)置進程組ID號
2、會話期:
會話期(session)是一個或多個進程組的集合。
setsid()函數(shù)可以建立一個對話期:
如果,調(diào)用setsid的進程不是一個進程組的組長,此函數(shù)創(chuàng)建一個新的會話期。
?。?)此進程變成該對話期的首進程
?。?)此進程變成一個新進程組的組長進程。
?。?)此進程沒有控制終端,如果在調(diào)用setsid前,該進程有控制終端,那么與該終端的聯(lián)系被解除。 如果該進程是一個進程組的組長,此函數(shù)返回錯誤。
(4)為了保證這一點,我們先調(diào)用fork()然后exit(),此時只有子進程在運行
現(xiàn)在我們來給出創(chuàng)建守護進程的所需步驟:
編寫守護進程的一般步驟:
?。?)在父進程中執(zhí)行fork并exit推出;
?。?)在子進程中調(diào)用setsid函數(shù)創(chuàng)建新的會話;
?。?)在子進程中調(diào)用chdir函數(shù),讓根目錄 ”/” 成為子進程的工作目錄;
(4)在子進程中調(diào)用umask函數(shù),設(shè)置進程的umask為0;
?。?)在子進程中關(guān)閉任何不需要的文件描述符
說明:
?。?)在后臺運行。
為避免掛起控制終端將Daemon放入后臺執(zhí)行。方法是在進程中調(diào)用fork使父進程終止,讓Daemon在子進程中后臺執(zhí)行。
if(pid=fork())
exit(0);//是父進程,結(jié)束父進程,子進程繼續(xù)
?。?)脫離控制終端,登錄會話和進程組
有必要先介紹一下Linux中的進程與控制終端,登錄會話和進程組之間的關(guān)系:進程屬于一個進程組,進程組號(GID)就是進程組長的進程號(PID)。登錄會話可以包含多個進程組。這些進程組共享一個控制終端。這個控制終端通常是創(chuàng)建進程的登錄終端。
控制終端,登錄會話和進程組通常是從父進程繼承下來的。我們的目的就是要擺脫它們,使之不受它們的影響。方法是在第1點的基礎(chǔ)上,調(diào)用setsid()使進程成為會話組長:
setsid();
說明:當(dāng)進程是會話組長時setsid()調(diào)用失敗。但第一點已經(jīng)保證進程不是會話組長。setsid()調(diào)用成功后,進程成為新的會話組長和新的進程組長,并與原來的登錄會話和進程組脫離。由于會話過程對控制終端的獨占性,進程同時與控制終端脫離。
?。?) 禁止進程重新打開控制終端
現(xiàn)在,進程已經(jīng)成為無終端的會話組長。但它可以重新申請打開一個控制終端??梢酝ㄟ^使進程不再成為會話組長來禁止進程重新打開控制終端:
if(pid=fork())
exit(0);//結(jié)束第一子進程,第二子進程繼續(xù)(第二子進程不再是會話組長)
?。?)關(guān)閉打開的文件描述符
進程從創(chuàng)建它的父進程那里繼承了打開的文件描述符。如不關(guān)閉,將會浪費系統(tǒng)資源,造成進程所在的文件系統(tǒng)無法卸下以及引起無法預(yù)料的錯誤。按如下方法關(guān)閉它們:
for(i=0;i 關(guān)閉打開的文件描述符close(i);>
?。?) 改變當(dāng)前工作目錄
進程活動時,其工作目錄所在的文件系統(tǒng)不能卸下。一般需要將工作目錄改變到根目錄。對于需要轉(zhuǎn)儲核心,寫運行日志的進程將工作目錄改變到特定目錄如/tmpchdir("/")
?。?)重設(shè)文件創(chuàng)建掩模
進程從創(chuàng)建它的父進程那里繼承了文件創(chuàng)建掩模。它可能修改守護進程所創(chuàng)建的文件的存取位。為防止這一點,將文件創(chuàng)建掩模清除:umask(0);
?。?)處理SIGCHLD信號
處理SIGCHLD信號并不是必須的。但對于某些進程,特別是服務(wù)器進程往往在請求到來時生成子進程處理請求。如果父進程不等待子進程結(jié)束,子進程將成為僵尸進程(zombie)從而占用系統(tǒng)資源。如果父進程等待子進程結(jié)束,將增加父進程的負擔(dān),影響服務(wù)器進程的并發(fā)性能。在Linux下可以簡單地將SIGCHLD信號的操作設(shè)為SIG_IGN。
signal(SIGCHLD,SIG_IGN);
這樣,內(nèi)核在子進程結(jié)束時不會產(chǎn)生僵尸進程。這一點與BSD4不同,BSD4下必須顯式等待子進程結(jié)束才能釋放僵尸進程。
三、創(chuàng)建守護進程
在創(chuàng)建之前我們先了解setsid()使用:
2026-02-13
Linux下的crontab定時執(zhí)行任務(wù)命令詳解2026-02-13
Linux系統(tǒng)下tar壓縮解壓縮命令詳解2026-02-14
linux系統(tǒng)如何清理和避免僵尸進程?linux如何編輯bashrc配置文件?使用macOS或Linux發(fā)行版的用戶可能都發(fā)現(xiàn)了,在電腦用戶主目錄中有許多的隱藏文件,其中.bashrc的配置文件最為常用,通過編輯bashrc配置文件可以提高...
2026-02-13
Linux系統(tǒng)如何安裝使用ProcDump for Linux?ProcDump for Linux是Windows版Sysinternals套件中ProcDump工具的Linux 構(gòu)建版,專為Linux 開發(fā)人員提供,開發(fā)人員可以根據(jù)性能觸發(fā)器...
2026-02-12