Linux編程之《守護進程》,linux《守護進程》

來源:互聯網
上載者:User

Linux編程之《守護進程》,linux《守護進程》

Intro

-----

守護進程,也就是通常說的Daemon進程,是Linux中的後台服務進程。它是一個生存期較長的進程,通常獨立於控制終端並且周期性地執行某種任務或等待處理某些發生的事件。守護進程常常在系統引導裝入時啟動,在系統關閉時終止。Linux系統有很多守護進程,大多數服務都是通過守護進程實現的,同時,守護進程還能完成許多系統任務,例如,作業規划進程crond、列印進程lqd等(這裡的結尾字母d就是Daemon的意思)。

由於在Linux中,每一個系統與使用者進行交流的介面稱為終端,每一個從此終端開始啟動並執行進程都會依附於這個終端,這個終端就稱為這些進程的控制終端,當控制終端被關閉時,相應的進程都會自動關閉。但是守護進程卻能夠突破這種限制,它從被執行開始運轉,直到整個系統關閉時才退出。如果想讓某個進程不因為使用者或終端或其他地變化而受到影響,那麼就必須把這個進程變成一個守護進程,下面將完整代碼貼上。

  1 /************************************************  2  * 該常式講解Linux守護進程的編程方法  3 ************************************************/  4 #include <unistd.h>  5 #include <signal.h>  6 #include <sys/param.h>  // NOFILE  7 #include <sys/stat.h>   // umask  8 #include <stdio.h>  9 #include <stdlib.h> 10 #include <time.h> 11 #include <assert.h> 12  13 bool initDaemon() 14 { 15     // 屏蔽一些有關控制終端操作的訊號 16     // 防止守護進程沒有正常運轉起來時,因控制終端受到幹擾退出或掛起 17     assert(signal(SIGINT, SIG_IGN) != SIG_ERR); // 終端中斷 18     assert(signal(SIGHUP, SIG_IGN) != SIG_ERR); // 串連掛斷 19     assert(signal(SIGQUIT, SIG_IGN) != SIG_ERR);// 終端退出 20     assert(signal(SIGPIPE, SIG_IGN) != SIG_ERR);// 向無讀進程的管道寫資料 21     assert(signal(SIGTTOU, SIG_IGN) != SIG_ERR);// 背景程式嘗試寫操作 22     assert(signal(SIGTTIN, SIG_IGN) != SIG_ERR);// 背景程式嘗試讀操作 23     assert(signal(SIGTERM, SIG_IGN) != SIG_ERR);// 終止 24  25     // [1] 建立一個子進程,父進程退出 26     int pid = fork(); 27     if (pid) 28     { 29         // 父進程退出 30         exit(0); 31     } 32     else if (pid < 0) 33     { 34         return false; 35     } 36  37     // 子進程繼續運行 38      39     // [2] 在子進程中建立新的會話,setsid有三個作用 40     // a.讓進程擺脫原會話的控制 41     // b.讓進程擺脫原進程組的控制 42     // c.讓進程擺脫原控制終端的控制 43     int ret = setsid(); 44     if (ret < 0) 45     { 46         return false; 47     } 48  49     // [3] 禁止進程重新開啟控制終端 50     // 進程已經成為無終端的交談群組長,但它可以重新申請開啟一個控制終端 51     // 可以通過使進程不再成為交談群組長來禁止進程重新開啟控制終端 52     pid = fork(); 53     if (pid) 54     { 55         // 結束第一個子進程 56         exit(0); 57     } 58     else if (pid < 0) 59     { 60         return false; 61     } 62  63     // 第二個子進程繼續運行 64  65     // [4] 關閉開啟的檔案描述符 66     // 進程從建立它的父進程那裡繼承了開啟的檔案描述符,如果不關閉,將會浪費系統資源, 67     // 造成進程所在的檔案系統無法卸下以及引起無法預料的錯誤 68     for (int i = 0; i < NOFILE; ++i) 69     { 70         close(i); 71     } 72  73     // [5] 改變當前工作目錄 74     // 進程活動時,其工作目錄所在的檔案系統不能卸下,一般將工作目錄改變到根目錄 75     ret = chdir("/"); 76     if (ret < 0) 77     { 78         return false; 79     } 80  81     // [6] 重新設定檔案建立掩碼 82     // 進程從建立它的父進程那裡繼承了檔案建立掩碼,它可能修改守護進程所建立的檔案的存取位 83     // 所以將檔案建立掩碼清除 84     umask(0); 85  86     return true; 87 } 88  89 int main() 90 { 91     // 初始化守護進程 92     bool ret = initDaemon(); 93     if (!ret) 94     { 95         printf("Init daemon failed\n"); 96         return 1; 97     } 98  99     FILE* file = NULL;100     time_t t = 0;101 102     // 每隔10秒向test.log報告運行狀態103     while (true)104     {105         sleep(10);106         file = fopen("./var/test.log", "a+");107         if (file != NULL)108         {109             t = time(NULL);110             fprintf(file, "I am here at %s\n", asctime(localtime(&t)));111             fclose(file);112         }113     }114 115     return 0;116 }

 

該例子的github地址:https://github.com/chxuan/samples/blob/master/Daemon/Daemon.cpp

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.