国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 操作系統 > 正文

守護進程之編程規則

2024-06-28 13:28:06
字體:
來源:轉載
供稿:網友
守護進程之編程規則

在編寫守護進程時需遵循一些基本規則,以便防止產生并不需要的交互作用。下面先說明這些規則,然后給出一個按照這些規則編寫的函數daemonize。

(1)首先要做的是調用umask將文件模式創建屏蔽字設置為0。由繼承得來的文件模式創建屏蔽字可能會拒絕設置某些權限。例如,若守護進程要創建一個組可讀、寫的文件,而繼承的文件模式創建屏蔽字可能屏蔽了這兩種權限,于是所要求的組可讀、寫就不能起作用。

(2)調用fork,然后使父進程退出(exit)。這樣做實現了下面幾點:第一,如果該守護進程是作為一條簡單shell命令啟動的,那么父進程終止使得shell認為這條命令已經執行完畢(也就沒有了控制終端);第二,子進程繼承了父進程的進程組ID,但具有一個新的進程ID,這就保證了子進程不是一個進程組的組長進程。這對于下面就要做的setsid調用是必要的前提條件。

(3)調用setsid以創建一個新會話。于是執行http://www.CUOXin.com/nufangrensheng/p/3513400.html中列舉的三個操作,使調用進程:(a)成為新會話的首進程,(b)成為一個新進程組的組長進程,(c)沒有控制終端。

在基于系統V的系統中,有些人建議在此時再次調用fork,并使父進程終止。第二個子進程作為守護進程繼續運行。這樣就保證了該守護進程不是會話首進程,于是按照系統V規則(見http://www.CUOXin.com/nufangrensheng/p/3513443.html)可以防止它取得控制終端。避免取得控制終端的另一種方法是,無論何時打開一個終端設備都一定要指定O_NOCTTY。

(4)將當前工作目錄更改為根目錄。從父進程出繼承過來的當前工作目錄可能在一個掛載的文件系統(a mounted file system)中。因為守護進程通常在系統再引導之前是一直存在的,所以如果守護進程的當前工作目錄在一個掛載的文件系統中,那么該文件系統就不能被卸載。這與掛載文件系統的原意不符。

另外,某些守護進程可能會把當前工作目錄更改到某個指定位置,在那里做它們的工作,例如,行式打印機假脫機守護進程常常將其工作目錄更改到它們的spool目錄上。

(5)關閉不再需要的文件描述符。這使守護進程不再持有從其父進程繼承來的某些文件描述符(父進程可能是shell進程,或某個其他進程)。可以使用http://www.CUOXin.com/nufangrensheng/p/3496323.html中程序清單2-4中的open_max函數或getrlimit函數(http://www.CUOXin.com/nufangrensheng/p/3509262.html)來判定最高文件描述符值,并關閉直到該值的所有描述符。

(6)某些守護進程打開/dev/null使其具有文件描述符0、1和2,這樣,任何一個試圖讀標準輸入、寫標準輸出和標準出錯的庫例程都不會產生任何效果。因為守護進程并不與終端設備相關聯,所以不能在終端設備上顯示其輸出,也無處從交互式用戶那里接受輸入。即使守護進程是從交互式會話啟動的,但因為守護進程是在后臺運行的,所以登錄會話的終止并不影響守護進程。如果其他用戶在同一終端設備上登錄,我們也不會在該終端上見到守護進程的輸出,用戶也不可期望他們在終端上的輸入會由守護進程讀取。

實例

程序清單13-1是個函數,可由想初始化成為一個守護進程的程序調用。

程序清單13-1 初始化一個守護進程

#include "apue.h"#include <syslog.h>#include <fcntl.h>#include <sys/resource.h>voiddaemonize(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");    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 system from being unmounted.    */    if(chdir("/") < 0)        err_quit("%s: can't change directory to /");        /*    * 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);    }}

本篇博文內容摘自《UNIX環境高級編程》(第二版),僅作個人學習記錄所用。關于本書可參考:http://www.apuebook.com/


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 闵行区| 青田县| 临泉县| 贵溪市| 肃宁县| 长海县| 鸡泽县| 威宁| 佛教| 芷江| 沐川县| 思茅市| 息烽县| 丰县| 托克逊县| 神农架林区| 阿克陶县| 措勤县| 特克斯县| 古丈县| 漳平市| 芜湖市| 革吉县| 信宜市| 通州区| 深圳市| 边坝县| 漯河市| 合水县| 长汀县| 寻乌县| 沾化县| 浮山县| 奉化市| 凤冈县| 巴里| 肥乡县| 云阳县| 台江县| 德兴市| 天峨县|