青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

S.l.e!ep.¢%

像打了激速一樣,以四倍的速度運轉(zhuǎn),開心的工作
簡單、開放、平等的公司文化;尊重個性、自由與個人價值;
posts - 1098, comments - 335, trackbacks - 0, articles - 1
  C++博客 :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理

如何編寫UNIX DAEMON程序

Posted on 2011-01-28 21:47 S.l.e!ep.¢% 閱讀(587) 評論(0)  編輯 收藏 引用 所屬分類: Unix
如何編寫UNIX DAEMON程序
分享
2008-12-04 16:35

unix 進程可以運行在前臺或是后臺,運行在前臺的(9php.com)程序通過終端與用戶進行交互,而后以進程是單獨運行的(9php.com),用戶可以查看它的(9php.com)狀態(tài),但不清楚它具體在做什么。我們將運行在后臺的(9php.com)程序叫做"daemon"程序。如常見的(9php.com)httpd,nfsd,sshd都屬于"daemon"程序,要寫這樣的(9php.com)程序,你可能要考慮如下的(9php.com)一些處理。
1,后臺運行處理
使用FORK()調(diào)用創(chuàng)建一個子進程,然后讓父進程退出。這樣子進程就與父進程分離了并運行在后臺。
? ? i=fork();
? ? if (i<0) exit(1); /* fork error */
? ? if (i>0) exit(0); /* parent exits */
? ? /* child (daemon) continues */

2,進程依賴處理
每個子進程繼承父進程的(9php.com)控制終端,進程將會接收關(guān)聯(lián)終端的(9php.com)信號。為了防止daemon程序從創(chuàng)建它的(9php.com)進程接收信號,必需去除與控制終端的(9php.com)關(guān)聯(lián)。
在UNIX系統(tǒng)中,進程運行在一個進程組,子進程會從父進程繼承進程組,一個DAEMON進程應(yīng)該不依賴于進程組的(9php.com)其它進程.
  setsid() /* obtain a new process group */
這個函數(shù)將DAEMON進程放置于一個新的(9php.com)進程組,并去除了與控制終端的(9php.com)關(guān)聯(lián)。
3,繼承的(9php.com)文件描述符號和標準I/O處理
子進程會繼承父進程打開的(9php.com)文件描述符,這樣會導(dǎo)致文件描述符資源的(9php.com)浪費,所以應(yīng)該關(guān)閉所有繼承過來的(9php.com)文件描述符。
? ? for (i=getdtablesize();i>=0;--i) close(i); /* close all descriptors */
對于stdin,stdout,stderr,將它們重定向到/dev/null。
? ? i=open("/dev/null",O_RDWR); /* open stdin */
? ? dup(i); /* stdout */
? ? dup(i); /* stderr */
由于關(guān)閉了所有文件描述符,上面的(9php.com)操作會從0開始順序產(chǎn)生文件描述符。

4,文件掩碼處理
為了安全的(9php.com)考慮,需要將設(shè)置文件掩碼
  umask(027);

5,運行目錄處理
一個daemon進程應(yīng)該運行在一個固定的(9php.com)目錄,防止用戶在不同的(9php.com)目錄下運行程序后找不到相關(guān)的(9php.com)文件。
  chdir("/servers/");

6,保持單DAEMON進程處理
為了保持單daemon進程,防止運行多個daemon進程,有效的(9php.com)方式是建立一個文件,并對其加鎖,在進程退出時進行解鎖。
?? lfp=open("exampled.lock",O_RDWR|O_CREAT,0640);
? ? if (lfp<0) exit(1); /* can not open */
? ? if (lockf(lfp,F(xiàn)_TLOCK,0)<0) exit(0); /* can not lock */
? ? /* only first instance continues */

? ? sprintf(str,"%d\n",getpid());
? ? write(lfp,str,strlen(str)); /* record pid to lockfile */

7,信號處理
對于daemon進程要忽略和處理一些接收到的(9php.com)信號,如子進程結(jié)束時會發(fā)送SIGCHLD信號組父進程,有些daemon進程通過SIGHUP信號來重啟。
  signal(SIG_IGN,SIGCHLD); /* child terminate signal */
上面的(9php.com)代碼將忽略SIGCHLD信號。
  void Signal_Handler(sig) /* signal handler function */
? ? int sig;
? ? {
? ?? ???switch(sig){
? ?? ?? ?? ?case SIGHUP:
? ?? ?? ?? ?? ? /* rehash the server */
? ?? ?? ?? ?? ? break;? ?? ???
? ?? ?? ?? ?case SIGTERM:
? ?? ?? ?? ?? ? /* finalize the server */
? ?? ?? ?? ?? ? exit(0)
? ?? ?? ?? ?? ? break;? ?? ???
? ?? ???}? ?
? ? }

? ? signal(SIGHUP,Signal_Handler); /* hangup signal */
? ? signal(SIGTERM,Signal_Handler); /* software termination signal from kill */
??建立一個信號處理函數(shù),并與信號關(guān)聯(lián)。
8,日志處理
??運行程序有一些重要的(9php.com)信息需要記日志,有如下幾種方法記錄日志:
??重定向輸出到標準I/O,這種方式將日志直接輸出到終端(顯示器),實際上這個程序是運行在前臺的(9php.com)。這種方式不適用于daemon進程。
??寫日志文件,將日志寫入文件。
?? void log_message(filename,message)
? ? char *filename;
? ? char *message;
? ? {
? ? FILE *logfile;
? ?? ???logfile=fopen(filename,"a");
? ?? ???if(!logfile) return;
? ?? ???fprintf(logfile,"%s\n",message);
? ?? ???fclose(logfile);
? ? }

? ? log_message("conn.log","connection accepted");
? ? log_message("error.log","can not open file");
日志服務(wù):這種方式是將日志送給一個日志服務(wù),由日志服務(wù)來記錄日志,并提供查閱,
UNIX系統(tǒng)帶有SYSLOGD日志服務(wù),可以通過如下方式將日志寫入SYSLOGD。
  openlog("mydaemon",LOG_PID,LOG_DAEMON)
? ? syslog(LOG_INFO, "Connection from host %d", callinghostname);
? ? syslog(LOG_ALERT, "Database Error !");
? ? closelog();
就寫這么多了,要變成你自己的(9php.com)東東,還得你自己去研究.希望這篇文章對初學者有個指引.

Daemon設(shè)計原則

Daemon程序設(shè)計主要原則包括:

(1)?????? 程序運行后調(diào)用fork,并讓父進程退出。子進程獲得一個新的進程ID,但繼承了父進程的進程組ID。

(2)?????? 調(diào)用setsid創(chuàng)建一個新的session,使自己成為新session和新進程組的leader,并使進程沒有控制終端(tty)。

(3)?????? 設(shè)置文件創(chuàng)建mask為0,避免創(chuàng)建文件時權(quán)限的影響。

(4)?????? 關(guān)閉不需要的打開文件描述符。因為Daemon程序在后臺執(zhí)行,不需要于終端交互,通常就關(guān)閉STDIN、STDOUT和STDERR。其它根據(jù)實際情況處理。

(5)?????? Daemon無法輸出信息,可以使用SYSLOG或自己的日志系統(tǒng)進行日志處理。(可選)

(6)?????? 編寫管理Daemon的SHELL腳本,使用service對Daemon進行管理和監(jiān)控。(可選)

Daemon程序框架

int init_daemon(void)

{

? pid_t pid;

? int i;

?

? /* parent exits , child continues */

? if((pid = fork()) < 0)

??? return -1;

? else if(pid != 0)

??? exit(0);

?

? setsid(); /* become session leader */

? for(i=0;i< NOFILE ;++i) /* close STDOUT, STDIN, STDERR, */

??? close(i);

?

? umask(0); /* clear file mode creation mask */

? return 0;

}

?

void sig_term(int signo)

{

? if(signo == SIGTERM)? /* catched signal sent by kill(1) command */

? {

???? wsio_logit("", "wsiod stopped\n");

???? exit(0);

 }

}

?

/* main program of daemon */

int main(void)

{

if(init_daemon() == -1){

printf("can't fork self\n");

exit(0);

? }

? wsio_logit("", "wsiod started\n");

? signal(SIGTERM, sig_term); /* arrange to catch the signal */

?

? while (1) {

??? // Do what you want here

??? … …

? }

? exit(0);

}

Daemon日志

這里使用自己的日志系統(tǒng),當然也可以使用SYSLOG。

#define LOGBUFSZ 256???? /*log buffer size*/

#define LOGFILE? "/var/log/wsiod.log"? /*log filename*/

int wsio_logit(char * func, char *msg, ...)

{

??????? va_list args;

??????? char prtbuf[LOGBUFSZ];

??????? int save_errno;

??????? struct tm *tm;

??????? time_t current_time;

??????? int fd_log;

?

??????? save_errno = errno;

??????? va_start (args, msg);

??????? (void) time (&current_time);??????????? /* Get current time */

??????? tm = localtime (&current_time);

??????? sprintf (prtbuf, "%02d/%02d %02d:%02d:%02d %s ", tm->tm_mon+1,

??????????????????? tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec, func);

??????? vsprintf (prtbuf+strlen(prtbuf), msg, args);

??????? va_end (args);

??????? fd_log = open (LOGFILE, O_WRONLY | O_CREAT | O_APPEND, 0664);

??????? write (fd_log, prtbuf, strlen(prtbuf));

??????? close (fd_log);

??????? errno = save_errno;

??????? return 0;

}

Daemon管理

Daemon程序可以使用service工具進行管理,包括啟動、停止、查看狀態(tài)等,但前題是需要編寫一個如下的簡單SHELL腳本。

# /etc/rc.d/init.d/wsiod

#!/bin/sh

#

# wsiod???????? This shell script takes care of starting and stopping wsiod.

#

# chkconfig: 35 65 35

# description: wsiod is web servce I/O server, which is used to access files on remote hosts.

?

# Source function library.

. /etc/rc.d/init.d/functions

?

# Source networking configuration.

. /etc/sysconfig/network

?

# Check that networking is up.

[ ${NETWORKING} = "no" ] && exit 0

?

RETVAL=0

prog="wsiod"

WSIOARGS="-h $HOSTNAME -p 80 -t STANDALONE -k -c -d"

start() {

??????? # Start daemons.

??????? echo -n $"Starting $prog: "

??????? daemon /usr/local/bin/wsiod ${WSIOARGS}

??????? RETVAL=$?

??????? echo

??????? [ $RETVAL -eq 0 ] && touch /var/lock/subsys/wsiod

??????? return $RETVAL

}

stop() {

??????? # Stop daemons.

??????? echo -n $"Shutting down $prog: "

??????? killproc wsiod

??????? RETVAL=$?

??????? echo

??????? [ $RETVAL -eq 0 ] && rm -f /var/lock/subsys/wsiod

??????? return $RETVAL

}

?

# See how we were called.

case "$1" in

? start)

??????? start

??????? ;;

? stop)

?????? ?stop

??????? ;;

? restart|reload)

??????? stop

??????? start

??????? RETVAL=$?

??????? ;;

? status)

??????? status wsiod

??????? RETVAL=$?

??????? ;;

? *)

??????? echo $"Usage: $0 {start|stop|restart|status}"

??????? exit 1

esac

?

exit $RETVAL

?

OK,到這兒為止,一個完整的Linux Daemon程序就完成了。

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            一区二区三区成人| 欧美精品videossex性护士| 久久久久久穴| 精品成人国产| 欧美三级免费| 久久激情综合| 亚洲国产小视频| 亚洲欧美另类久久久精品2019| 国产自产在线视频一区| 欧美11—12娇小xxxx| 一本色道久久加勒比精品| 欧美与欧洲交xxxx免费观看| 亚洲国产91| 欧美亚洲第一区| 久色婷婷小香蕉久久| 一区二区三区精品| 蜜桃久久精品乱码一区二区| 在线亚洲伦理| 黄网动漫久久久| 欧美三区美女| 麻豆精品传媒视频| 亚洲欧美成人网| 亚洲狠狠婷婷| 久久伊人亚洲| 香蕉av福利精品导航| 最新中文字幕一区二区三区| 国产精品亚洲网站| 欧美激情精品久久久六区热门| 亚洲主播在线观看| 亚洲国产视频一区| 久久视频免费观看| 亚洲欧美乱综合| 亚洲精品色婷婷福利天堂| 国产一区av在线| 欧美涩涩网站| 欧美精品国产精品| 久久免费一区| 欧美一区二区免费视频| 99国内精品久久久久久久软件| 免费国产一区二区| 久久免费视频这里只有精品| 亚洲欧美日韩中文视频| 一区二区三区高清不卡| 亚洲欧洲日夜超级视频| 一区在线电影| 黄色成人在线网址| 国产亚洲综合性久久久影院| 国产精品videosex极品| 欧美精品一区二区三区蜜臀 | 羞羞视频在线观看欧美| 日韩午夜在线观看视频| 亚洲激情欧美激情| 亚洲国产日韩一区| 亚洲第一福利社区| 欧美黑人国产人伦爽爽爽| 猫咪成人在线观看| 久久精视频免费在线久久完整在线看| 亚洲一线二线三线久久久| 亚洲一区激情| 亚洲午夜国产一区99re久久| 一本色道久久综合亚洲精品高清 | 欧美母乳在线| 你懂的国产精品| 欧美国产第二页| 欧美电影美腿模特1979在线看| 欧美aⅴ一区二区三区视频| 免费欧美日韩| 欧美国产日韩一区二区在线观看| 老鸭窝91久久精品色噜噜导演| 久久久久中文| 欧美成在线视频| 欧美日韩国产小视频在线观看| 欧美伦理在线观看| 欧美视频在线观看| 国产精品揄拍500视频| 国产亚洲制服色| 在线精品视频一区二区| 亚洲人成网站精品片在线观看| 日韩午夜在线观看视频| 亚洲午夜精品视频| 久久国产精品久久精品国产| 久久综合久久综合久久综合| 欧美黄色免费| 亚洲最新视频在线| 亚洲欧美国产视频| 久久婷婷综合激情| 欧美乱大交xxxxx| 国产精品一区在线播放| 狠狠网亚洲精品| 亚洲精品国久久99热| 亚洲永久在线观看| 久久中文久久字幕| 亚洲精品日韩欧美| 亚洲欧美日韩另类| 蜜桃av一区二区| 欧美亚州一区二区三区 | 欧美专区一区二区三区| 美国十次成人| 一本色道久久综合狠狠躁篇的优点| 亚洲欧美日韩一区二区| 榴莲视频成人在线观看| 欧美四级电影网站| 尤物九九久久国产精品的特点 | 久久成人免费电影| 欧美黄色免费| 午夜精品视频在线观看| 免费黄网站欧美| 国产精品有限公司| 亚洲美女电影在线| 久久久99爱| 亚洲美女91| 久久青草福利网站| 国产精品免费观看视频| 91久久中文字幕| 久久久精品免费视频| 亚洲乱码精品一二三四区日韩在线| 午夜精品久久久久久久99热浪潮| 欧美国产三级| 狠色狠色综合久久| 亚洲欧美久久久久一区二区三区| 欧美国产日韩在线| 校园春色国产精品| 国产精品久久国产精麻豆99网站| 亚洲黄色影片| 久久三级视频| 亚洲一区在线观看视频| 欧美精品一区二区三区久久久竹菊| 红桃视频国产精品| 性色av一区二区怡红| 99在线精品视频| 欧美国产日韩精品免费观看| 激情综合自拍| 久久久亚洲影院你懂的| 亚洲一级黄色片| 欧美日韩免费在线视频| 亚洲精品韩国| 欧美激情亚洲精品| 久久亚洲私人国产精品va媚药| 国产香蕉久久精品综合网| 亚洲在线第一页| 亚洲美女在线观看| 欧美精品一区二区三区久久久竹菊| 亚洲国产精品一区二区www在线| 久久久99国产精品免费| 性欧美长视频| 国产日韩欧美成人| 久久精品91久久香蕉加勒比| 亚洲午夜免费视频| 欧美亚洲成人精品| 亚洲一区日韩| 亚洲少妇自拍| 国产精品网站在线播放| 亚洲在线观看免费| 亚洲一二三区精品| 国产欧美大片| 久久国产一区二区| 性欧美1819sex性高清| 国产亚洲精品福利| 久久久91精品国产| 久久久久九九九九| 亚洲国产欧美一区二区三区同亚洲| 蜜桃精品一区二区三区| 免费久久精品视频| 一本久久综合| 亚洲视频欧美视频| 国产欧美不卡| 美日韩精品视频| 欧美成人午夜视频| 亚洲精品美女在线| av成人免费观看| 国产精品日韩欧美一区| 久久久久国色av免费看影院| 久久精品亚洲热| 亚洲人成绝费网站色www| 亚洲美女视频| 国产伦精品一区二区三区免费 | 亚洲欧美在线aaa| 精品99一区二区三区| 亚洲成色777777在线观看影院| 欧美有码在线视频| 欧美在线播放| 日韩视频第一页| 亚洲在线一区二区| 在线精品国产成人综合| 亚洲欧洲日本mm| 国产精品日韩精品| 欧美**人妖| 国产精品www.| 欧美1区2区3区| 国产精品av免费在线观看| 久久精品在线播放| 欧美久久久久免费| 久久精品视频在线观看| 欧美本精品男人aⅴ天堂| 亚洲影院免费观看| 久久男人资源视频| 亚洲欧美久久久| 老**午夜毛片一区二区三区| 亚洲一区免费网站| 久久裸体艺术|