守護進程

来源:http://www.cnblogs.com/gdk-0078/archive/2016/01/26/5161776.html
-Advertisement-
Play Games

為什麼要引入守護進程: 因為它生存期長,它獨立於控制終端、會話周期(下文有解釋)執行任務: 由於在linux中,每一個系統與用戶進行交流的界面稱為終端,每一個從此終端開始運行的進程都會依賴這個終端,這個終端就稱為這些進程的控制終端。當控制終端被關閉時,相應的進程都會自動關閉。但是守護進程卻能...


  • 為什麼要引入守護進程:


     

   因為它生存期長,它獨立於控制終端、會話周期(下文有解釋)執行任務:

   由於在linux中,每一個系統與用戶進行交流的界面稱為終端,每一個從此終端開始運行的進程都會依賴這個終端,這個終端就稱為這些進程的控制終端。當控制終端被關閉時,相應的進程都會自動關閉。但是守護進程卻能突破這種限制,它被執行開始運轉,直到整個系統關閉時才退出。

  • 守護進程的特性:


     

     1> 守護進程最重要的特性是後臺運行。

   2> 其次,守護進程必須與其運行前的環境隔離開來。這些環境包括未關閉的文件描述符、控制終端、會話和進程組、工作目錄已經文件創建掩碼等。這些環境通常是守護進程從父進程那裡繼承下來的。

   3> 守護進程的啟動方式有其特殊之處:它可以在linux系統啟動時從啟動腳本/etc/rc.d中啟動,可以由作業規划進程crond啟動,還可以由用戶終端(通常是shell)執行。

  • 後臺進程 == 守護進程?


     

   在linux下使用&可以使程式進入後臺運行模式,使用守護進程方法也可以使程式和終端分離出來,那麼後臺進程是否就是守護進程?其實兩者不相等!

   最直觀最重要的區別,守護進程沒有控制終端,而後臺進程有。

  1.基本上任何一個程式都可以後臺運行,但守護進程是具有特殊要求的程式,比如要脫離自己的父進程,成為自己的會話組長等,這些要在代碼中顯式地寫出來。

  2.守護進程成為了進程組長(或者會話組長),和控制終端失去了聯繫(其文件描述符也是繼承於父進程的,但是在變成守護進程的同時stdin,stdout,stderr和控制台失去聯繫了)。

  3.後臺的文件描述符也是繼承於父進程,例如shell,所以它也可以再當前終端下顯式輸出數據,但是daemon進程自己變成了進程組長,其文件描述符號和控制終端沒有關聯,是脫離控制台的進程。

  小結:守護進程肯定是後臺進程,但反之不成立。守護進程顧名思義,主要用於一些長期運行,守護著自己的職責(監聽埠,監聽服務等)。我們的系統下就有很多守護進程。

  • 守護進程編程規則(步驟):


     

  step 1、在後臺運行

一些概念: 

  • 進程組:是一個或多個進程的集合。進程組有進程組ID來唯一標識。除了進程號(PID)之外,進程組ID(GID)也是一個進程的必備屬性。每個進程都有一個組長進程,其組長進程的進程號等於進程組ID。且該進程組ID不會因為組長進程的退出而受影響。
  •   會話周期:會話期是一個或多個進程組的集合。通常,一個會話開始於用戶登錄,終止於用戶退   出,在此期間該用戶運行的所有進程都屬於這個會話期。
  •   控制終端:由於在linux中,每一個系統與用戶進行交流的界面稱為終端,每一個從此終端開始運行 的進程都會依賴這個控制終端。

    為避免掛起控制終端,將daemon放入後臺執行,方法是進程中調用fork,然後使父進程exit,讓daemon在後臺執行。這樣做實現了以下兩點:

  1.如果該守護進程是作為一條簡單的shell命令啟動的,那麼父進程終止會讓shell認為這條命令已經執行完畢。

  2.雖然紫禁城繼承了父進程的進程組ID(pgid),但獲得了一個新的進程ID(pid),這就保證了子進程不是一個進程組的組長進程,這是下麵要進行的setsid調用的先決條件!

    控制終端,登錄會話和進程組通常是從父進程繼承下來的。我們的目的就是要擺脫它們,使之不受它們的影響。

進程調用 setsid函數建立一個新會話

 

1 #include<unistd.h>
2 pid_t setsid(void);

 

如果調用此函數的進程不是一個進程組的組長,則此函數創建一個新會話,會發生以下3件事

1.該進程會變成新回話的會話首進程(session leader,會話首進程是創建該會話的進程)。此時,該進程是新會話中的唯一進程。(擺脫原會話的控制)

2.該進程成為一個新進程組的組長進程,新進程組ID是該調用進程的進程ID。(擺脫原進程組的控制)

3.該進程沒有控制終端。如果在調用setsid之前該進程有一個控制終端,那麼這種聯繫也被切斷。(擺脫控制終端)

step 2:在子進程中調用setsid創建一個新會話。這會執行上面的3件事!

  通過這一步,新的子進程就擺脫了原會話的控制,擺脫了原進程組的控制,擺脫了終端的控制。

step 3:禁止進程重新打開控制終端//可省,很多開源服務沒有fork第二次

  現在,進程已經成為無終端的會話組長了。

   但它可以重新申請打開一個控制終端。可以通過使進程不再成為會話組長來禁止進程重新打開控制終端。

   因為打開一個控制終端的前提條件是該進程必須是會話組長!所以再fork一次,結束第一子進程,第二子進程繼續(第二子進程不再是會話組長),第二子進程ID != sid(sid是進程第一子進程的會ID:sid)。所以無法打開新的控制終端。

step 4 :將當前目錄更改為根目錄

  從父進程處繼承過來的當前工作目錄可能在一個掛載的文件系統中。因為守護進程通常在系統再引導之前是一直存在的,所以如果守護進程的當前工作目錄在一個掛載文件系統中,那麼該文件系統就不能被卸載。

  或者,某些守護進程還可能會把當前工作目錄更改到某個指定的位置,併在此位置進行它們的全部工作。例如,行式印表機假離線守護進程就可能將其工作目錄更改到它們的spool目錄上。

step 5:關閉所有(不再需要的)文件描述符

  新進程會從父進程(父進程可能是shell進程,或某個其他進程)那裡繼承一些已經打開了的文件。這些被打開的文件可能永遠不會被守護進程讀寫,而它們一直消耗系統資源。另外守護進程已經與所屬的終端失去聯繫,那麼從終端輸入的字元不可能到達守護進程。可以使用open_max函數或getrlimit函數來判定最高文件描述符值,並關閉0直到該值的所有描述符。

 strp 6:重設文件掩碼

  進程從創建它的父進程那裡繼承了文件創建掩碼。它可能修改守護進程所創建的文件的存取位。即調用umask將文件模式創建屏蔽字設置為一個已知(通常為0)。

step 7:處理SIGCHLD信號

    處理SIGCHLD信號並不是必須的。但對於某些進程,特別是伺服器進程往往在請求到來時生成子進程處理請求。如果父進程不等待子進程結束,子進程將成為 僵屍進程(zombie)從而占用系統資源。如果父進程等待子進程結束,將增加父進程的負擔,影響伺服器進程的併發性能。在Linux下可以簡單地將 SIGCHLD信號的操作設為SIG_IGN。 

  signal(SIGCHLD,SIG_IGN); 

  這樣,內核在子進程結束時不會產生僵屍進程。這一點與BSD4不同,BSD4下必須顯式等待子進程結束才能釋放僵屍進程。

 


 

  • 無代碼無真相!
 1 #include <stdio.h>
 2 #include <stdlib.h>
 3 #include <unistd.h>
 4 #include <sys/stat.h>
 5 void Daemon()
 6 {
 7       const int MAXFD=64;
 8       int i=0;
 9       if(fork()!=0)    //父進程退出
10           exit(0);
11       setsid();        //成為新進程組組長和新會話領導,脫離控制終端
12       chdir("/");    //設置工作目錄為根目錄
13       umask(0);        //重設文件訪問許可權掩碼
14       for(;i<MAXFD;i++) //儘可能關閉所有從父進程繼承來的文件
15           close(i);
16 }
17 int main()
18 {
19       Daemon(); //成為守護進程
20       while(1){
21           sleep(1);
22       }
23       return 0;
24 }

 

 

(未完,待完善)

 

 

 

 

 

 

 

     

   

  

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 利用分類,NSString,增加一個方法。#import #import @interface NSString (Height)+ (CGSize)getRect:(NSString *)textStr andWidth:(CGSize)size andFont:(UIFont *)font;@e...
  • SQL Server代理是所有實時資料庫的核心。代理有很多不明顯的用法,因此系統的知識,對於開發人員還是DBA都是有用的。這系列文章會通俗介紹它的很多用法。在以前的文章里我們看到,SQL Server代理由一系列的作業步驟組成,每個作業步驟是要進行的不同工作類型。SQL Server代理也提供創建警...
  • 獲取【下載地址】 QQ: 313596790 【免費支持更新】A 代碼生成器(開發利器); 增刪改查的處理類,service層,mybatis的xml,SQL( mysql 和oracle)腳本, jsp頁面 都生成 就不用寫搬磚的代碼了,生成的放到項目里,可以直接運行B 阿裡巴巴資料庫連接池dr....
  • 一、簡介Redis是一種高級key-value資料庫,數據可以持久化,支持的數據類型很豐富,有字元串,哈希,鏈表,集合和有序集合5種數據類型Redis支持在伺服器端計算集合的並,交和補集(difference)等,還支持多種排序功能,所以Redis也可以被看成是一個數據結構伺服器Redis的所有數據...
  • 安裝首先是下載,地址奉上:http://www.google.cn/chrome/browser/desktop/index.html,選擇64 bit .rpm (適用於 Fedora/openSUSE) ,當然如果你是32位系統那麼你可以選擇32 bit .rpm (適用於 Fedora/ope...
  • 這是一塊便宜 (¥12.5)的 WiFi 模塊,3.3V ,晶元是樂鑫科技(Espressif)出品。它本身是很多玩法,比如這個 NodeMCU (淘寶有套件焊接好一整套的帶 USB 介面的,搜 esp8266 nodemcu)。 我這是沒多久之前買的。要買的話,多幾塊錢可以有更完整引腳的版本,樂鑫...
  • 一、命令[root@localhost ~]# free -m total used free shared buffers cachedMem: 7869 7651 218 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...