精品国产人成在线_亚洲高清无码在线观看_国产在线视频国产永久2021_国产AV综合第一页一个的一区免费影院黑人_最近中文字幕MV高清在线视频

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

Linux中如何編寫守護進程程序

麥辣雞腿堡 ? 來源:嵌入式Linux系統開發 ? 作者:Jasonangel ? 2023-10-07 17:12 ? 次閱讀

守護進程(Daemon)也稱為精靈進程,是運行在后臺的一種特殊進程,它獨立于控制終端并且周期性地執行某種任務或等待處理某些事情的發生,主要表現為以下兩個特點:

? 長期運行。守護進程是一種生存期很長的一種進程,它們一般在系統啟動時開始運行,除非強行終止,否則直到系統關機都會保持運行。與守護進程相比,普通進程都是在用戶登錄或運行程序時創建,在運行結束或用戶注銷時終止,但守護進程不受用戶登錄注銷的影響,它們將會一直運行著、直到系統關機。

? 與控制終端脫離。在 Linux 中,系統與用戶交互的界面稱為終端,每一個從終端開始運行的進程都會依附于這個終端,這是上一小節給大家介紹的控制終端,也就是會話的控制終端。當控制終端被關閉的時候,該會話就會退出,由控制終端運行的所有進程都會被終止,這使得普通進程都是和運行該進程的終端相綁定的;但守護進程能突破這種限制,它脫離終端并且在后臺運行,脫離終端的目的是為了避免進程在運行的過程中的信息在終端顯示并且進程也不會被任何終端所產生的信息所打斷。

守護進程是一種很有用的進程。Linux 中大多數服務器就是用守護進程實現的,譬如,Internet 服務器 inetd、Web 服務器 httpd 等。同時,守護進程完成許多系統任務,譬如作業規劃進程 crond 等。

守護進程 Daemon,通常簡稱為 d,一般進程名后面帶有 d 就表示它是一個守護進程。守護進程與終端無任何關聯,用戶的登錄與注銷與守護進程無關、不受其影響,守護進程自成進程組、自成會話,即pid=gid=sid。通過命令"ps -ajx"查看系統所有的進程,如下所示:

圖片TTY 一欄是問號?表示該進程沒有控制終端,也就是守護進程,其中 COMMAND 一欄使用中括號[]括起來的表示內核線程,這些線程是在內核里創建,沒有用戶空間代碼,因此沒有程序文件名和命令行,通常采用 k 開頭的名字,表示 Kernel。

編寫守護進程程序

  1. 創建子進程、終止父進程。父進程調用 fork()創建子進程,然后父進程使用 exit()退出,這樣做實現了下面幾點。第一,如果該守護進程是作為一條簡單地 shell 命令啟動,那么父進程終止會讓 shell 認為這條命令已經執行完畢。第二,雖然子進程繼承了父進程的進程組ID,但它有自己獨立的進程ID,這保證了子進程不是一個進程組的組長進程,這是下面將要調用 setsid 函數的先決條件!
  2. 子進程調用 setsid 創建會話。setsid()函數創建新的會話,由于之前子進程并不是進程組的組長進程,所以調用 setsid()會使得子進程創建一個新的會話,子進程成為新會話的首領進程,同樣也創建了新的進程組、子進程成為組長進程,此時創建的會話將沒有控制終端。所以這里調用 setsid 有三個作用:讓子進程擺脫原會話的控制、讓子進程擺脫原進程組的控制和讓子進程擺脫原控制終端的控制。在調用 fork 函數時,子進程繼承了父進程的會話、進程組、控制終端等,雖然父進程退出了,但原先的會話期、進程組、控制終端等并沒有改變,因此,那還不是真正意義上使兩者獨立開來。setsid 函數能夠使子進程完全獨立出來,從而脫離所有其他進程的控制。
  3. 將工作目錄更改為根目錄。子進程是繼承了父進程的當前工作目錄,由于在進程運行中,當前目錄所在的文件系統是不能卸載的,這對以后使用會造成很多的麻煩。因此通常的做法是讓“/”作為守護進程的當前目錄,當然也可以指定其 它目錄來作為守護進程的工作目錄。
  4. 重設文件權限掩碼 umask。文件權限掩碼 umask 用于對新建文件的權限位進行屏蔽,在 5.5.5 小節中有介紹。由于使用 fork 函數新建的子進程繼承了父進程的文件權限掩碼,這就給子進程使用文件帶來了諸多的麻煩。因此,把文件權限掩 碼設置為 0,確保子進程有最大操作權限、這樣可以大大增強該守護進程的靈活性。設置文件權限掩碼的函數是 umask,通常的使用方法為 umask(0)。
  5. 關閉不再需要的文件描述符。子進程繼承了父進程的所有文件描述符,這些被打開的文件可能永遠不會被守護進程(此時守護進程指的就是子進程,父進程退出、子進程成為守護進程)讀或寫,但它們一樣消耗系統資源,可能導致所在的文件系統無法卸載,所以必須關閉這些文件,這使得守護進程不再持有從其父進程繼承過來的任何文件描述符。
  6. 將文件描述符號為 0、1、2 定位到/dev/null。將守護進程的標準輸入、標準輸出以及標準錯誤重定向到/dev/null,這使得守護進程的輸出無處顯示、也無處從交互式用戶那里接收輸入。
  7. 忽略 SIGCHLD 信號。處理 SIGCHLD 信號不是必須的,但對于某些進程,特別是并發服務器進程往往是特別重要的,服務器進程在接收到客戶端請求時會創建子進程去處理該請求,如果子進程結束之后,父進程沒有去 wait 回收子進程,則子進程將成為僵尸進程;如果父進程 wait 等待子進程退出,將又會增加父進程的負擔、也就是增加服務器的負擔,影響服務器進程的并發性能,在 Linux 下,可以將 SIGCHLD 信號的處理方式設置為SIG_IGN,也就是忽略該信號,可讓內核將僵尸進程轉交給 init 進程去處理,這樣既不會產生僵尸進程、又省去了服務器進程回收子進程所占用的時間。
#include < stdio.h >
#include < stdlib.h >
#include < unistd.h >
#include < sys/types.h >
#include < sys/stat.h >
#include < fcntl.h >
#include < signal.h >
int main(void) {
   pid_t pid;
   int i;
   /* 創建子進程 */
   pid = fork();
   if (0 > pid) {
     perror("fork error");
     exit(-1);
   }
   else if (0 < pid)//父進程
     exit(0); //直接退出
   /*
   *子進程
   */
   /* 1.創建新的會話、脫離控制終端 */
   if (0 > setsid()) {
   perror("setsid error");
   exit(-1);
   }
   /* 2.設置當前工作目錄為根目錄 */
   if (0 > chdir("/")) {
     perror("chdir error");
     exit(-1);
   }
   /* 3.重設文件權限掩碼 umask */
   umask(0);
   /* 4.關閉所有文件描述符 */
   for (i = 0; i < sysconf(_SC_OPEN_MAX); i++)
     close(i);
   /* 5.將文件描述符號為 0、1、2 定位到/dev/null */
   open("/dev/null", O_RDWR);
   dup(0);
   dup(0);
   /* 6.忽略 SIGCHLD 信號 */
   signal(SIGCHLD, SIG_IGN);
   /* 正式進入到守護進程 */
   for ( ; ; ) {
     sleep(1);
     puts("守護進程運行中......");
   }
   exit(0);
}

整個代碼的編寫都是根據上面的介紹來完成的。運行之后,沒有任何打印信息輸出,原因在于守護進程已經脫離了控制終端,它的打印信息并不會輸出顯示到終端,在代碼中已經將標準輸入、輸出以及錯誤重定位到了/dev/null,/dev/null 是一個黑洞文件,自 然是看不到輸出信息。

守護進程可以通過終端命令行啟動,但通常它們是由系統初始化腳本進行啟動,譬如/etc/rc*或 /etc/init.d/*等。

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • Linux
    +關注

    關注

    87

    文章

    11123

    瀏覽量

    207908
  • 終端
    +關注

    關注

    1

    文章

    1080

    瀏覽量

    29724
  • 程序
    +關注

    關注

    115

    文章

    3720

    瀏覽量

    80357
  • 系統
    +關注

    關注

    1

    文章

    1002

    瀏覽量

    21217
收藏 人收藏

    評論

    相關推薦

    Linux守護進程

    1.守護進程概述 守護進程,也就是通常所說的daemon進程,是Linux
    發表于 08-22 09:17

    Linux進程間通信方式-管道

    應用程序開發》熱點鏈接:1、Linux進程間通信2、實驗:編寫守護進程3、實驗:
    發表于 08-29 15:29

    實驗:編寫進程程序

    1.實驗目的 通過編寫進程程序,使讀者熟練掌握fork()、exec()、wait()和waitpid()等函數的使用,進一步理解在Linux
    發表于 09-05 15:32

    Linux學習雜談】之守護進程以及簡單創建

    首先我們需要了解一下什么叫做守護進程,以及我們為什么需要這樣的進程。我們知道當我們寫一個簡單的程序的時候我們知道,這個程序比如說printf
    發表于 09-27 13:28

    初學者嵌入式linux系統的學習步驟

    /O 編寫串口通信程序 編寫多串口通信程序7、嵌入式系統進程
    發表于 01-18 10:34

    Linux守護進程詳解

    分享到:標簽:進程控制 Linux 守護進程進程 7.3 Linux
    發表于 10-18 14:24 ?0次下載
    <b class='flag-5'>Linux</b><b class='flag-5'>守護</b><b class='flag-5'>進程</b>詳解

    進程控制開發之編寫進程程序實驗解析

    7.4.1 編寫進程程序 1.實驗目的 通過編寫進程程序,使讀者熟練掌握fork()、exe
    發表于 10-18 16:33 ?0次下載
    <b class='flag-5'>進程</b>控制開發之<b class='flag-5'>編寫</b>多<b class='flag-5'>進程</b><b class='flag-5'>程序</b>實驗解析

    Linux系統網絡驅動程序編寫

    驅動程序編寫 一.Linux系統設備驅動程序概述 1.1 Linux設備驅動程序分類 1.2
    發表于 11-07 10:40 ?0次下載

    嵌入式linux系統的學習步驟

    串口通信 熟悉文件I/O 編寫串口通信程序 編寫多串口通信程序 7、嵌入式系統進程
    發表于 07-23 13:59 ?921次閱讀

    你知道嵌入式linux系統下簡單守護進程(daemon)的編寫

    嵌入式linux設備創建一個守護進程,用于保護系統的主進程,防止某些不可預期的意外導致主
    發表于 04-23 15:16 ?1351次閱讀
    你知道嵌入式<b class='flag-5'>linux</b>系統下簡單<b class='flag-5'>守護</b><b class='flag-5'>進程</b>(daemon)的<b class='flag-5'>編寫</b>?

    學會用日志了解你的 Linux 系統

    Linux 系統日志非常重要,后臺運行的程序(通常被稱為守護進程或者服務進程)處理了你 Linux
    發表于 05-06 16:39 ?684次閱讀

    linux守護進程實例

      今天完成一個守護進程實驗。  1 熟悉守護進程編寫和調試(系統日志)  2 編寫
    發表于 04-02 14:42 ?356次閱讀

    如何編寫基于ARM的裸機程序和基于Linux的驅動程序

    在嵌入式開發,ADC應用比較頻繁,本文主要講解ADC的基本原理以及如何編寫基于ARM的裸機程序和基于Linux的驅動程序
    的頭像 發表于 09-13 09:25 ?3192次閱讀
    如何<b class='flag-5'>編寫</b>基于ARM的裸機<b class='flag-5'>程序</b>和基于<b class='flag-5'>Linux</b>的驅動<b class='flag-5'>程序</b>

    Linux 安全模塊:守護進程和套接字

    守護進程通常是在后臺觀察操作以等待狀態、服務于特定子系統并確定整個系統的操作規則的實用程序。例如,一個守護進程被配置為監控打印服務的狀態。
    發表于 08-26 10:01 ?596次閱讀

    文盤Rust--把程序作為守護進程啟動

    當我們寫完一個服務端程序,需要上線部署的時候,或多或少都會和操作系統的守護進程打交道,畢竟誰也不希望shell關閉既停服。今天我們就來聊聊這個事兒。
    的頭像 發表于 11-07 10:22 ?967次閱讀