Linux編程之《守護進程》

来源:http://www.cnblogs.com/highway-9/archive/2016/05/17/5500341.html
-Advertisement-
Play Games

Intro 守護進程,也就是通常說的Daemon進程,是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


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

-Advertisement-
Play Games
更多相關文章
  • ...
  • smbpasswd命令的常用方法smbpasswd -a 增加用戶(該賬戶必須存在於/etc/passwd文件中)smbpasswd -d 凍結用戶,就是這個用戶不能在登錄了smbpasswd -e 解凍用戶,讓凍結的用戶可以在使用smbpasswd -n 把用戶的密碼設置成空. 要在global中 ...
  • 1.去http://redis.io/download下載redis-2.8.24.tar.gz 2.解壓redis-2.8.24.tar.gz並安裝 3.創建redis用戶和數據存儲目錄 4.複製redis.conf文件到/etc目錄下,並修改文件 主伺服器上修改配置文件redis.conf 從服 ...
  • 1.在主從伺服器上/etc/yum.repos.d/目錄下創建文件mongodb.repo,它包含MongoDB倉庫的配置信息,內容如下: 2.在主從伺服器上執行安裝命令 3.在主從伺服器上自定義db和log存放路徑 新建存放DB目錄,修改許可權 主伺服器修改/etc/mongod.conf logp ...
  • 防火牆的初始化 廢話不多說,先上一張表格: 清空預設表(filter表)中的數據,只要簡單的使用下麵這條命令即可: 清除預設表中INPUT鏈的規則,可使用下麵的命令: 命令執行完成後,使用iptables -L查看當前防火牆設置。 給鏈設置預設策略基本語法如下: 其中archy是鏈的名稱,targe ...
  • 1:/etc/passwd 打開該文件,可以看到每一行內容被分割成了7個欄位比如:root:x:0:0:root:/root:/bin/bash 第一個欄位表示用戶名為root用戶 第二個欄位存放了該賬號的密碼,早期unix是存放在這,出於安全考慮,改為存放在/etc/shadow 這裡用x替代 第 ...
  • 簡介: PHP FastCGI 優點 1、PHP 腳本運行速度更快。PHP 解釋程式被載入記憶體而不用每次需要時從存儲器讀取,極大的提升了依靠腳本運行站點的性能。 2、需要使用的系統資源更少。由於伺服器不再每次需要時都載入 PHP 解釋程式,可以將站點的傳輸速度提升很多而不必增加 CPU 負擔。 3、 ...
  • 位置大概: ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...