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

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

守護進程之守護進程的慣例

2024-06-28 13:28:05
字體:
來源:轉載
供稿:網友
守護進程之守護進程的慣例

在UNIX系統中,守護進程遵循下列公共慣例:

  • 若守護進程使用鎖文件,那么該文件通常存放在/var/run目錄中。注意,守護進程可能需要具有超級用戶權限才能在此目錄下創建文件。鎖文件的名字通常是name.pid,其中,name是該守護進程或服務的名字。例如cron守護進程鎖文件的名字是/var/run/crond.pid。
  • 若守護進程支持配置選項,那么配置文件通常存放在/etc目錄中。配置文件的名字通常是name.conf,其中,name是該守護進程或服務的名字。例如,syslogd守護進程的配置文件是/etc/syslog.conf。
  • 守護進程可用命令行啟動,但通常它們是由系統初始化腳本之一(/etc/rc*或/etc/init.d/*)啟動的。如果在守護進程終止時,應當自動地重新啟動它,則我們可在/etc/inittab中為該守護進程包括_respawn記錄項,這樣,init就將重啟動該守護進程。
  • 若一守護進程有一配置文件,那么當該守護進程啟動時,它讀該文件,但在此之后一般就不會再查看它。若一管理員更改了配置文件,那么該守護進程可能需要被停止,然后再啟動,以使配置文件的更改生效。為避免此種麻煩,某些守護進程將捕捉SIGHUP信號,當它們接收到該信號時,重讀配置文件。因為守護進程并不與終端相結合,它們或者是無控制終端的會話首進程,或者是孤兒進程組的成員,所以守護進程并不期望接收SIGHUP。于是,它們可以安全地重復使用它。

實例

程序清單13-3所示程序說明了守護進程可以重讀其配置文件的一種方法。該程序使用sigwait以及多線程(可參考http://www.CUOXin.com/nufangrensheng/p/3540453.html)。

程序清單13-3 守護進程重讀配置文件

#include "apue.h"#include <pthread.h>#include <syslog.h>sigset_t    mask;extern int already_running(void);void reread(void){    /* ... */}void *thr_fn(void *arg){    int err, signo;    for(;;)    {        err = sigwait(&mask, &signo);        if(err != 0)        {            syslog(LOG_ERR, "sigwait failed");            exit(1);        }            switch(signo)        {            case SIGHUP:                syslog(LOG_INFO, "Re-reading configuration file");                reread();                break;                    case SIGTERM:                syslog(LOG_INFO, "got SIGTERM; exiting");                exit(0);            default:                syslog(LOG_INFO, "unexpected signal %d/n", signo);        }    }    return(0);}intmain(int argc, char *argv[]){    int                 err;    pthread_t           tid;    char                *cmd;    struct sigaction    sa;        if((cmd = strrchr(argv[0], '/')) == NULL)        cmd = argv[0];    else        cmd++;        /*    * Become a daemon.    */        daemonize(cmd);    /*    * Make sure only one copy of the daemon is running.    */    if(already_running())    {            syslog(LOG_ERR, "daemon already running");        exit(1);    }    /*    * Restore SIGHUP default and block all signals.    */    sa.sa_handler = SIG_DFL;    sigemptyset(&sa.sa_mask);    sa.sa_flags = 0;    if(sigaction(SIGHUP, &sa, NULL) < 0)        err_quit("%s: can't restore SIGHUP default");    sigfillset(&mask);    if((err = pthread_sigmask(SIG_BLOCK, &mask, NULL)) != 0)        err_exit(err, "SIG_BLOCK error");    /*    * Create a thread to handle SIGHUP and SIGTERM.    */    err = pthread_create(&tid, NULL, thr_fn, 0);    if(err != 0)        err_exit(err, "can't create thread");        /*    * PRoceed with the rest of the daemon.    */    /* ... */    exit(0);}

該程序調用http://www.CUOXin.com/nufangrensheng/p/3544104.html中的daemonize以初始化守護進程。從該函數返回后,調用http://www.CUOXin.com/nufangrensheng/p/3544370.html中的already_running函數以確保該守護進程只有一個副本在運行。到達這一點時,SIGHUP信號仍被忽略(???),所以需要恢復對該信號的系統默認處理方式;否則調用sigwait的線程決不會見到該信號。

如同對多線程程序所推薦的那樣,我們阻塞所以信號,然后創建一線程,由它來處理信號。該線程的唯一工作是等待SIGHUP和SIGTERM。當接收到SIGHUP信號時,該線程調用reread函數重讀它的配置文件。當它接收到SIGTERM信號時,記錄一消息,然后終止。

回憶http://www.CUOXin.com/nufangrensheng/p/3514157.html中的表10-1,對于SIGHUP和SIGTERM的默認動作是終止進程。因為我們阻塞了這些信號,所以當對進程產生這些信號時,守護進程不會消亡,而是調用sigwait的線程在返回時將指示已接收到該信號。

實例

如在http://www.CUOXin.com/nufangrensheng/p/3540453.html中所說的那樣,linux線程對于信號的處理方式與眾不同。由于這一點,在程序清單13-3中對信號標識合適的進程是困難的。另外,由于實現的差別,不能保證守護進程將按所期望的那樣作出反應。

程序清單13-4說明守護進程無需使用多線程也可以捕捉SIGHUP并重讀其配置文件。

#include "apue.h"#include <syslog.h>#include <errno.h>extern int lockfile(int);extern int already_running(void);void reread(void){    /* ... */}void sigterm(int signo){    syslog(LOG_INFO, "got SIGTERM; exiting");    exit(0);}voidsighup(int signo){    syslog(LOG_INFO, "Re-reading configuration file");    reread();}intmain(int argc, char *argv[]){        char            *cmd;    struct sigaction    sa;        if((cmd = strrchr(argv[0], '/')) == NULL)        cmd = argv[0];    else        cmd++;    /*    * Become a daemon.    */    daemonize(cmd);    /*    * Make sure only one copy of the daemon is running.    */    if(already_running())    {        syslog(LOG_ERR, "daemon already running");        exit(1);    }        /*    * Handle signals of interest.    */    sa.sa_handler = sigterm;    sigempty(&sa.sa_mask);    sigaddset(&sa.sa_mask, SIGHUP);    sa.sa_flags = 0;    if(sigaction(SIGTERM, &sa, NULL) < 0)    {        syslog(LOG_ERR, "can't catch SIGTERM: %s", strerror(errno));        exit(1);    }    sa.sa_handler = sighup;    sigemptyset(&sa.sa_mask);    sigaddset(&sa.sa_mask, SIGTERM);    sa.sa_flags = 0;    if(sigaction(SIGHUP, &sa, NULL) < 0)    {        syslog(LOG_ERR, "can't catch SIGHUP: %s", strerror(errno));        exit(1);    }    /*    * Proceed with the rest of the daemon.    */    /* ... */    exit(0);  }

在初始化守護進程后,我們為SIGHUP和SIGTERM配置信號處理程序。我們可以將重讀邏輯放在信號處理程序中,也可以只在其中設置一個標志,由守護進程的主線程做所有所需的工作。

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


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 鄢陵县| 广州市| 伊宁县| 孝义市| 中方县| 大田县| 盐边县| 铁岭市| 台山市| 麟游县| 裕民县| 册亨县| 贞丰县| 尉氏县| 雷波县| 禄劝| 星座| 酒泉市| 肃北| 亳州市| 灌南县| 富平县| 兰西县| 香港| 清徐县| 高要市| 海晏县| 定远县| 遵义市| 平度市| 岳阳市| 云南省| 霍林郭勒市| 米林县| 大英县| 深水埗区| 堆龙德庆县| 南通市| 泾川县| 阿尔山市| 鄱阳县|