1. 程式人生 > >[APUE chapter 13] 守護程序

[APUE chapter 13] 守護程序

作者:isshe
日期:2016.10.30
郵箱:[email protected]
github: https://github.com/isshe

1. 相關概念

  • 系統程序以賴於作業系統實現。
  • 父程序ID為0的各程序通常是核心程序,它們作為系統引導裝入過程的一部分而啟動。
  • 核心守護程序以無控制終端方式啟動,使用者層守護程序缺少控制終端可能是守護程序呼叫了setsid的結果。
  • 大多數使用者層守護程序都是程序組的組長程序以及會話的首程序,而且是這些程序組和會話中的唯一程序。(rsyslogd例外,linux中)
  • 使用者層守護程序的父程序是init程序(linux系統中)。
  • 守護程序常作伺服器程序。

2. 編寫規則

編寫守護程序程式時需遵循一些基本規則,以防產生不必要的互動。

  • 1.呼叫umask將檔案模式建立遮蔽字設定為一個已知值(通常是0)(不理解)
  • 2.呼叫fork,然後父程序exit。這樣可以:

    如果該守護程序是為一條簡單的shell命令啟動的,那麼父程序終止會讓shell認為這條命令已經執行完畢。
    子程序繼承父程序的程序組ID,但獲得新的程序ID,保證了子程序不是一個程序組的組長程序。

  • 3.呼叫setsid建立一個新會話。 會發生:(因為前面保證了此程序不是程序組的組長,所以可以建立新會話,否則,setsid會返回出錯)

    1). 該程序程式設計新會話的會話首程序(session leader),此時此程序是會話中唯一程序。
    2). 該程序成為新程序組的組長程序。(新程序組ID就是呼叫程序ID)
    3). 程序沒有控制終端。

  • 4.將當前工作目錄更改為根目錄。

  • 5.關閉不需要的檔案描述符。(可以使用open_max函式或getrlimit函式獲取最大檔案描述符值)
  • 6.某些程序開啟/dev/null使其具有檔案描述符0、1、2。

3. 出錯記錄

  • 由於沒有控制終端,不能簡單地輸出到標準錯誤上。
  • 每個守護程序的出錯資訊寫到一個檔案也不好,管理起來會十分麻煩。

3.1 syslog

  • syslog設施的詳細組織結構:
    這裡寫圖片描述

  • 三種產生日誌訊息的方法:

    • 核心例程可以呼叫log函式。任何一個使用者程序可以通過開啟(open)並讀取(read)/dev/klog裝置來讀取這些資訊。
    • 呼叫syslog函式產生日誌訊息。
    • 無論使用者程序是在此主機上,還是通過TCP/IP網路連線到此主機的其他主機上,都可以將日誌訊息發向UDP埠514。
  • 原型:

       #include <syslog.h>

       void openlog(const char *ident, int option, int facility);
       void syslog(int priority, const char *format, ...);
       void closelog(void);
       int setlogmask(int mask);
  • 功能:(日誌訊息通過syslogd守護程序讀取)
    • openlog:開啟該程序的日誌。(呼叫是可選的。如不呼叫,則在第一次呼叫syslog時自動呼叫。)
    • closelog:關閉用於與syslogd守護程序進行通訊的描述符。(也是可選的。)
    • syslog:產生一個日誌訊息。
    • setlogmask:用於設定程序的記錄優先順序遮蔽字。
  • 引數:

    • ident:可以被加到每則日誌中的標識。一般是程式名稱。
    • open:(以下表格不完全完整,完整見APUE p378)

      option XSI 說明
      LOG_CONS * 若日誌訊息不能通過UNIX域資料表送至syslogd,則將該訊息寫至控制檯。
      LOG_NDELAY * 立即開啟至syslogd守護程序的UNIX域資料報套接字,不要等到第一條訊息已經被記錄時再開啟。(通常,在記錄第一條訊息之前,不開啟該套接字)
      LOG_NOWAIT * 不要等待在將訊息記入日誌過程中可能已建立的子程序。
      LOG_ODELAY * 在第一條訊息被記錄之前延遲開啟至syslogd守護程序的連線。
      LOG_PERROR 將日誌訊息傳送給syslogd外,還將它寫到標準錯誤。
      LOG_PID * 記錄每條訊息都要包含程序ID
    • facility:設定facility引數的目的是可以讓配置檔案說明,來自不同設施的訊息將以不同的方式處理。(中文表格見APUE p378)
      這裡寫圖片描述

    • priority:是facility和level的組合,以下是level的表格:
      這裡寫圖片描述
    • format:format引數以及其他所有format後的引數,都傳至vsprintf函式一遍進行格式化。format中每個%m字元都先被替換成與errno值對應的strerror。
    • mask:記錄優先順序遮蔽字。
  • 返回值:
    • setlogmask:返回呼叫setlogmask之前的遮蔽字。

3.2 例項

openlog("lpd", LOG_PID, LOG_LPR);
syslog(LOG_ERR, "open error for %s: %m", filename);
或
syslog(LOG_ERR|LOG_LPR, "open error for %s: %m", filename);

4. 守護程序的慣例

  • 在UNIX系統中,守護程序通常遵循下列通用慣例:
    • 若守護程序使用鎖檔案,那麼該檔案通常儲存在/var/run目錄中。(需要特權才能建立檔案,鎖的名字通常是name.pid,其中name是該守護程序或服務的名字)
    • 若守護程序支援配置選項,那麼配置檔案通常存放在/etc目錄中。(配置檔名字通常是namd.conf,name同上)
    • 守護程序可用命令列啟動,但通常它們是系統初始化指令碼之一啟動的(指令碼如:/etc/rc* 或 /etc/init.d/*)。(如要終止後自動重啟,則在/etc/inittab中為該守護程序寶貨respawn記錄項)
    • 若一個守護程序有一個配置檔案,那麼當該守護程序啟動時會讀該文,但此後一般不會再檢視它。

5. 參考資料

  • 《unix環境高階程式設計》第13章

相關推薦

[APUE chapter 13] 守護程序

作者:isshe 日期:2016.10.30 郵箱:[email protected] github: https://github.com/isshe

《JavaScript高級程序設計》Chapter 13 事件

motion nta 規範化 detach 等價 this指向 記錄 del reat 小記 JS與HTML之間的交互通過事件實現,事件發生在交互的瞬間,可以使用事件監聽器(或者事件處理程序)來預定時間。DOM2事件模塊盡量對事件進行規範,然而DOM3又增加了一些額外的處理

13程序員打工之路,卻從未停止創業!

java 程序員 創業 全國高考,每年這個時候,我都在總結人生,思緒未來!13年前我參加了高考,接著進入了程序員的生活,這坑太深,我無法自拔,然後我就在程序員行當苦逼了13年!畢業後,我在外企當了好幾年程序員,也在知名機構當過好多年IT講師,也曾嘗試過創業!逼於生活我還是穩打穩紮的在企業打工,畢竟

數據庫 chapter 13 數據庫技術新發展

運行 屬性 完整性 har .cn memory 面向 功能 數據結構 第十三章 數據庫技術新發展 數據模型是數據庫系統的核心和基礎。 按照數據模型的發展,數據庫技術可相應地分為三個發展階段: 第一代的網狀、層次數據庫系統 第二代的關系數據庫系統 第三代數據庫系統為核心的數

Android Studio無法啟動 Gradle ,無法啟動守護程序

bsp fin tar gradle ace option star brush intro Error:Unable to start the daemon process. This problem might be caused by incorrect confi

零元學Expression Blend 4 - Chapter 13 用實例了解布局容器系列-「Pathlistbox」I

清空 path ets arc 結合 des log box alt 原文:零元學Expression Blend 4 - Chapter 13 用實例了解布局容器系列-「Pathlistbox」I

MySQL Crash Course #06# Chapter 13. 14 GROUP BY. 子查詢

idt rom pla most con height bsp them 找到 索引 理解 GROUP BY 過濾數據 vs. 過濾分組 GROUP BY 與 ORDER BY 之不成文的規定 子查詢 vs. 聯表查詢 相關子查詢和不相關子查詢. 增量構造復雜

linux守護程序小結

建立守護程序步驟: 建立子程序父程序退出, 讓這個子程序變成孤兒程序, 防止產生殭屍程序 在子程序中建立新會話 setsid函式用於建立一個新的會話,並使得當前程序成為新會話組的組長 setsid函式能夠使程序完全獨立出來,從 而脫離所有其他程序的控制。 改

python程序守護程序

標籤(空格分隔): 守護程序 主程序建立子程序,然後將該程序設定成守護自己的程序,守護程序就好比崇禎皇帝身邊的老太監,崇禎皇帝已死老太監就跟著殉葬了; 關於守護程序需要強調兩點: 其一:守護程序會在主程序程式碼執行結束後就終止 其二:守護程序內無法再開啟子程序,否則丟擲異常:Assert

PHP-Websockets 上傳檔案2 優化支援php socket客戶端和websocket連線websocket伺服器 以守護程序方式執行編碼

WebsocketServer: users.php <?php class WebSocketUser { public $socket; public $id; public $headers = array(); public $handsh

php 編寫linux守護程序

問題:將一個php程式以linux守護程序(在後臺執行)的方式執行? 解決方法:(見程式碼) // index.php檔案 <?php /*實現守護程序化,當你的PHP程式需要轉為後臺執行時, 只需要呼叫一次封裝好的函式init()即可。 編寫守護程序的一般步驟步驟:

守護程序 互斥鎖 程序間通訊

1. 守護程序: from multiprocessing import Process import time def task(): print("11111111111111") time.sleep(3) print("22222222222

第三十六天 守護程序 互斥鎖 程序間通訊

一.昨日回顧 1. 程序 相關概念   併發 看起來像是同時執行的中 本質是不停切換執行 多個程序隨機執行   並行 同一時刻 多個程序 同時進行 只有多喝處理器才有真正的並行   序列 一個一個 依次排隊執行   阻塞 遇到了I/O操作 看起來就是程式碼卡住了   非阻塞 不會卡住程式碼的執行

Python學習的第36天程序守護程序、互斥鎖

一、守護程序: 1、守護程序: 本質就是一個"子程序",該"子程序"的生命週期<=被守護程序的生命週期,當一個程序作為守護程序時 被被守護的程序死亡時 守護程序也跟隨死亡 2、使用 from multiprocessing import Process import time def ta

13程序監控指令碼-getPID.sh

#!/bin/bash # get size of java process PID PName=$1 #echo $PName if [ "$PName" != "" ];then pid=`ps aux | grep $PName | grep -v grep

Cpp Chapter 13: Class Inheritance Part1

class inheritance lets you derive new classes from old ones, inheriting its properties of the old class, called the base class With inheritance, you can: 1

用shell寫守護程序指令碼

 一個udhcpd與udhcpc的守護,目前只會用shell模仿編寫,還有什麼方法可以做守護呢? #! /bin/sh #程序名字可修改 PRO_NAME=udhcpc WLAN=ra0 while true ; do # 用ps獲取$PRO_NAME程序數量 N

centos7 守護程序

ASP.NET Core應用程式釋出linux在shell中執行是正常的。可一但shell關閉網站也就關閉了,所以要配置守護程序, 用的是Supervisor,本文主要記錄配置的過程和過程遇到的問題 安裝Supervisor 1  yum install python-setu

Docker學習之守護程序

在讀《第一本Docker書》這本教程時,遇到Docker守護程序這個概念。首先需要理解守護程序是什麼,自然也就知道Docker守護程序的含義。 守護程序來自於Linux系統下的一部分,對於不太熟悉Linux系統的我來說,暫時只要知道守護程序是幹什麼的就可以了,所以寫一下我在查閱資料後對守護程序的

用Linux守護程序檢測某個程式是否執行

實現功能: 做的一個嵌入式板子開機會自啟動一個程式,但發現它工作數天後會退出。檢查記憶體使用並沒有洩漏,於是編寫了一個守護程序來不斷檢查程式是否執行,沒執行則執行它,這是一個折衷的辦法。   說明: 需要執行的程式是AlarmInterface,位於目錄/rf/下面。我做了