麻豆小视频在线观看_中文黄色一级片_久久久成人精品_成片免费观看视频大全_午夜精品久久久久久久99热浪潮_成人一区二区三区四区

首頁 > 系統 > Unix > 正文

《Unix環境高級編程》讀書筆記 第13章-守護進程

2024-06-28 13:24:23
字體:
來源:轉載
供稿:網友
《Unix環境高級編程》讀書筆記 第13章-守護進程1. 引言
  • 守護進程是生存期長的一種進程。它們常常在系統引導裝入時啟動,僅在系統關閉時才終止。它們沒有控制終端,在后臺運行。
  • 本章說明守護進程結構、如何編寫守護進程程序、守護進程如何報告出錯情況。
2. 守護進程的特征
  • 基于BSD的系統下執行:ps -axj

    -a 顯示由其他用戶所擁有的進程的狀態;-x 顯示沒有控制終端的進程狀態;-j 顯示與作業有關的信息

  • 基于System V的系統下執行:ps -efj
  • linux下執行以上兩個命令輸出一致
  • 常見的守護進程:
  • kswapd,內存換頁守護進程。
  • flush守護進程在可用內存達到設置的最小閥值時將臟頁面沖洗至磁盤。
  • sync_supers守護進程定期將文件系統元數據沖洗至磁盤。
  • jbd守護進程幫助實現了ext4文件系統中的日志功能。
  • rpcbind守護進程提供了將遠程過程調用程序號映射為網絡端口號的服務。
  • rsyslogd守護進程可以被由管理員啟用的將系統消息記入日志的任何程序使用。
  • inetd守護進程。超級因特網服務進程。
  • crond守護進程在定期安排的日期和時間執行命令。
  • atd守護進程,允許用戶在指定的時間執行任務,但是每個任務只執行一次。
  • sshd守護進程提供了安全的遠程登錄和執行設施。
  • cuPSD守護進程,打印假脫機進程,處理對系統提出的各個打印請求。
3. 編程規則
  • 在編寫守護進程程序時需遵循一些基本規則,以防止產生不必要的交互作用。
    1. 調用umask將文件模式創建屏蔽字設置為一個已知值(通常為0)。
    2. 調用fork,然后使父進程exit。因為:第一,如果守護進程是通過shell啟動的,這可以讓shell認為這條命令已經執行完畢;第二,子進程繼承了父進程的進程組ID,但獲得一個新的進程ID,這保證了子進程不是一個進程組的組長進程。這是setsid的先決條件。
    3. 調用setsid創建一個新會話。使調用進程:a. 成為新會話的首進程;b. 成為一個新進程組的組長進程;c. 沒有控制終端
    4. 將當期工作目錄更改為根目錄,以免占有某文件系統,使得其不能被卸載。或者,某寫守護進程還可能把當前工作目錄更改到某個指定位置。
    5. 關閉不再需要的文件描述符。使守護進程不再持有從其父進程繼承來的任何文件描述符。可以使用open_max函數或getrlimit函數來判定最高文件描述符的值,并關閉直到該值的所有描述符。
    6. 某些守護進程打開/dev/null使其具有文件描述符0、1、2 。這樣,任何一個試圖讀標準輸入、寫標準輸出或標準錯誤的庫例程都不會產生任何效果。
#include "apue.h"#include <syslog.h>#include <fcntl.h>#include <sys/resource.h>void daemonize(const char *cmd){  int i, fd0, fd1, fd2;  pid_t pid;  struct rlimit rl;  struct sigaction sa; /** Clear file creation mask.*/  umask(0); /** Get maximum number of file descriptors.*/  if (getrlimit(RLIMIT_NOFILE, &rl) < 0)    err_quit("%s: can’t get file limit", cmd); /** Become a session leader to lose controlling TTY.*/  if ((pid = fork()) < 0)    err_quit("%s: can’t fork", cmd);  else if (pid != 0) /* parent */    exit(0);  setsid(); /** Ensure future opens won’t allocate controlling TTYs.*/  sa.sa_handler = SIG_IGN;  sigemptyset(&sa.sa_mask);  sa.sa_flags = 0;  if (sigaction(SIGHUP, &sa, NULL) < 0)    err_quit("%s: can’t ignore SIGHUP", cmd);  if ((pid = fork()) < 0)    err_quit("%s: can’t fork", cmd);  else if (pid != 0) /* parent */    exit(0); /** Change the current working directory to the root so* we won’t PRevent file systems from being unmounted.*/  if (chdir("/") < 0)    err_quit("%s: can’t change directory to /", cmd); /** Close all open file descriptors.*/  if (rl.rlim_max == RLIM_INFINITY)    rl.rlim_max = 1024;  for (i = 0; i < rl.rlim_max; i++)    close(i); /** Attach file descriptors 0, 1, and 2 to /dev/null.*/  fd0 = open("/dev/null", O_RDWR);  fd1 = dup(0);  fd2 = dup(0); /** Initialize the log file.*/  openlog(cmd, LOG_CONS, LOG_DAEMON);  if (fd0 != 0 || fd1 != 1 || fd2 != 2) {    syslog(LOG_ERR, "unexpected file descriptors %d %d %d", fd0, fd1, fd2);  exit(1);  }}
4. 出錯記錄

  • 有以下3種產生日志消息的方法:
    1. 內核例程可以調用log函數。
    2. 大多數用戶進程(守護進程)調用syslog函數來產生日志消息。
    3. 無論一個用戶進程是在此主機上,還是在通過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 maskpri); Returns: previous log priority mask value5. 單實例守護進程
  • 為了正常運作,某些守護進程會實現為,在任一時刻只運行該守護進程的一個副本。
  • 文件和記錄鎖機制提供了一種保證一個守護進程只有一個副本在運行的方法。
#include <unistd.h>#include <stdlib.h>#include <fcntl.h>#include <syslog.h>#include <string.h>#include <errno.h>#include <stdio.h>#include <sys/stat.h>#define LOCKFILE "/var/run/daemon.pid"#define LOCKMODE (S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH)extern int lockfile(int); int already_running(void){  int fd;  char buf[16];  fd = open(LOCKFILE, O_RDWR|O_CREAT, LOCKMODE);  if (fd < 0) {    syslog(LOG_ERR, "can’t open %s: %s", LOCKFILE, strerror(errno));    exit(1);  }  if (lockfile(fd) < 0) {    if (errno == EACCES || errno == EAGAIN) {      close(fd);      return(1);    }    syslog(LOG_ERR, "can’t lock %s: %s", LOCKFILE, strerror(errno));    exit(1);  }  ftruncate(fd, 0);  sprintf(buf, "%ld", (long)getpid());  write(fd, buf, strlen(buf)+1);  return(0);}
6. 守護進程的慣例
  • 在Unix系統中,守護進程遵循以下通用慣例:
    1. 若守護進程使用鎖文件,那么該文件通常存儲在/var/run目錄中。守護進程可能需要具有超級用戶權限才能在此目錄中創建文件。鎖文件的名字通常是name.pid。
    2. 若守護進程支持配置選項,那么配置文件通常存放在/etc目錄中。配置文件的名字通常是name.conf。
    3. 守護進程可用命令行啟動,但通常它們是由系統初始化腳本之一啟動的。
    4. 某些守護進程捕捉SIGHUP信號,當它們接收到該信號時,重新讀配置文件。
7. 客戶進程-服務器進程模型
  • 守護進程常常用作服務器進程。
  • 一般而言,服務器進程等待客戶進程與其聯系,提出某種類型的服務要求。
  • 在服務器進程中調用fork然后exec另一個程序來項客戶進程提供服務是很常見的。服務器進程通常管理著多個文件描述符:通信端點、配置文件、日志文件和類似的文件。為保證安全,可設置所有對于被執行程序不需要的文件描述符的執行關閉標志close-on-exec。原創文章,轉載請聲明出處:http://www.CUOXin.com/DayByDay/p/3948402.html

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 一级黄色影院 | 国产一级毛片高清 | 一本色道久久综合亚洲精品小说 | 国产精品午夜一区 | xxxxxx视频| 91情侣在线偷精品国产 | 成人在线视频免费 | 黄色电影免费网址 | av在线不卡免费 | 久久精品视频黄色 | 香蕉秀 | 黄视频免费在线 | 激情久久一区二区 | 激情小视频在线观看 | 一级免费黄色免费片 | 欧美一级淫片007 | 精品国产一区二区三区四 | 亚洲va久久久噜噜噜久牛牛影视 | 久久国产精品久久久久 | 午夜91视频| 羞羞的视频在线 | 92看片淫黄大片欧美看国产片 | 国产精品区一区二区三区 | 羞羞视频免费视频欧美 | 久久久久久久网站 | 国产精品久久久久久久久久 | 激情视频日韩 | 91情侣在线偷精品国产 | 免费a视频| 国产69精品久久久久久久久久 | 亚洲第一精品在线 | 高清在线国产 | 性生活视频一级 | 欧美精品一区二区中文字幕 | av国产片 | 成人在线观看免费观看 | xfplay噜噜av| 日本不卡一区二区在线观看 | 中文在线日韩 | 91免费高清视频 | 国产精品久久国产精麻豆96堂 |