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

S.l.e!ep.¢%

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

如何編寫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)狀態,但不清楚它具體在做什么。我們將運行在后臺的(9php.com)程序叫做"daemon"程序。如常見的(9php.com)httpd,nfsd,sshd都屬于"daemon"程序,要寫這樣的(9php.com)程序,你可能要考慮如下的(9php.com)一些處理。
1,后臺運行處理
使用FORK()調用創建一個子進程,然后讓父進程退出。這樣子進程就與父進程分離了并運行在后臺。
? ? i=fork();
? ? if (i<0) exit(1); /* fork error */
? ? if (i>0) exit(0); /* parent exits */
? ? /* child (daemon) continues */

2,進程依賴處理
每個子進程繼承父進程的(9php.com)控制終端,進程將會接收關聯終端的(9php.com)信號。為了防止daemon程序從創建它的(9php.com)進程接收信號,必需去除與控制終端的(9php.com)關聯。
在UNIX系統中,進程運行在一個進程組,子進程會從父進程繼承進程組,一個DAEMON進程應該不依賴于進程組的(9php.com)其它進程.
  setsid() /* obtain a new process group */
這個函數將DAEMON進程放置于一個新的(9php.com)進程組,并去除了與控制終端的(9php.com)關聯。
3,繼承的(9php.com)文件描述符號和標準I/O處理
子進程會繼承父進程打開的(9php.com)文件描述符,這樣會導致文件描述符資源的(9php.com)浪費,所以應該關閉所有繼承過來的(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 */
由于關閉了所有文件描述符,上面的(9php.com)操作會從0開始順序產生文件描述符。

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

5,運行目錄處理
一個daemon進程應該運行在一個固定的(9php.com)目錄,防止用戶在不同的(9php.com)目錄下運行程序后找不到相關的(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_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)信號,如子進程結束時會發送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 */
??建立一個信號處理函數,并與信號關聯。
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");
日志服務:這種方式是將日志送給一個日志服務,由日志服務來記錄日志,并提供查閱,
UNIX系統帶有SYSLOGD日志服務,可以通過如下方式將日志寫入SYSLOGD。
  openlog("mydaemon",LOG_PID,LOG_DAEMON)
? ? syslog(LOG_INFO, "Connection from host %d", callinghostname);
? ? syslog(LOG_ALERT, "Database Error !");
? ? closelog();
就寫這么多了,要變成你自己的(9php.com)東東,還得你自己去研究.希望這篇文章對初學者有個指引.

Daemon設計原則

Daemon程序設計主要原則包括:

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

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

(3)?????? 設置文件創建mask為0,避免創建文件時權限的影響。

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

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

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

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日志

這里使用自己的日志系統,當然也可以使用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工具進行管理,包括啟動、停止、查看狀態等,但前題是需要編寫一個如下的簡單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>
            日韩视频中文| 欧美成在线视频| 另类天堂av| 久久成年人视频| 久久久久免费视频| 久久三级视频| 欧美激情国产日韩| 99国产精品久久| 亚洲欧美日韩一区二区在线 | 最新热久久免费视频| 欧美国产日韩在线观看| 亚洲精品在线电影| 亚洲欧美日韩一区二区三区在线观看| 欧美一级网站| 理论片一区二区在线| 久久久一本精品99久久精品66| 久久综合伊人77777尤物| 欧美电影专区| 国产精品亚洲аv天堂网| 影音先锋亚洲视频| 一区二区三区av| 久久人人看视频| 久久综合国产精品| 亚洲精品欧洲精品| 亚洲免费影视第一页| 欧美在线播放一区二区| 欧美成人免费大片| 亚洲视频每日更新| 久久久久国产精品人| 欧美精品久久99| 韩国精品主播一区二区在线观看| 亚洲精品国产精品国自产观看| 亚洲一区三区视频在线观看| 久久综合狠狠综合久久综合88| 日韩午夜在线电影| 狂野欧美激情性xxxx欧美| 国产精品高潮在线| 亚洲狼人精品一区二区三区| 久久精品综合| 一本久道久久久| 欧美成人精品三级在线观看| 国产主播精品| 欧美一区二区免费视频| 亚洲三级影院| 久久一区二区视频| 国产综合久久久久久| 亚洲欧美日韩精品久久| 亚洲国产一区二区a毛片| 久久九九全国免费精品观看| 国产伦精品免费视频| 亚洲一区二区三区免费视频| 91久久精品www人人做人人爽| 久久久国产精品一区二区中文| 国产精品一区2区| 香蕉久久一区二区不卡无毒影院| 亚洲日本中文字幕| 欧美成人精品影院| 亚洲国产欧美日韩| 欧美国产成人精品| 久久影音先锋| 亚洲国产免费看| 欧美激情成人在线| 欧美大成色www永久网站婷| 亚洲激情视频网站| 亚洲黑丝在线| 欧美人交a欧美精品| 99在线热播精品免费| 亚洲人成人一区二区在线观看| 欧美不卡在线| 一本大道av伊人久久综合| 亚洲欧洲精品一区二区三区不卡| 欧美国产日韩视频| 欧美高清不卡| 欧美一区二区三区成人| 国产农村妇女毛片精品久久莱园子 | 一区二区三区偷拍| 国产精品二区影院| 欧美亚洲一区二区三区| 亚洲综合成人在线| 黄色日韩网站| 亚洲国产精品一区二区www| 欧美精品高清视频| 亚洲欧美中文日韩v在线观看| 亚洲一级在线| 精品盗摄一区二区三区| 亚洲高清视频一区二区| 国产精品videosex极品| 久久国产黑丝| 欧美精品二区| 欧美一区二区三区男人的天堂 | 欧美一区免费视频| 久久婷婷久久| 中文一区二区在线观看| 午夜精品久久久久久久久久久久久 | 国产日韩一区二区三区在线播放| 久久久福利视频| 欧美成年人网站| 欧美一级在线视频| 蜜臀久久99精品久久久久久9| 一区二区三区**美女毛片| 午夜精品在线| 在线亚洲自拍| 男人的天堂亚洲| 欧美中文在线观看国产| 欧美va天堂在线| 久久黄色级2电影| 欧美日本在线观看| 免费观看欧美在线视频的网站| 欧美午夜在线| 亚洲精美视频| 亚洲国产精品传媒在线观看| 亚洲午夜电影| 一区二区三区精品在线| 久久这里有精品15一区二区三区 | 亚洲成色精品| 国产日韩一区二区三区在线播放| 亚洲欧洲日产国产综合网| 国产一在线精品一区在线观看| 亚洲精品自在久久| 91久久亚洲| 久久亚洲国产成人| 久久久久国内| 国产精品伊人日日| av成人免费在线| 日韩视频在线免费观看| 麻豆成人小视频| 快射av在线播放一区| 国产欧美日韩另类视频免费观看 | 蜜桃av一区| 久久免费少妇高潮久久精品99| 欧美网站在线| 99精品免费| 国产精品99久久久久久www| 欧美大片在线看| 欧美激情精品久久久六区热门 | 国产精品免费网站| 日韩性生活视频| 在线视频日本亚洲性| 欧美—级在线免费片| 最新国产成人av网站网址麻豆| 亚洲激情视频| 欧美精品乱码久久久久久按摩| 亚洲国产欧美国产综合一区 | 国产精品毛片在线| 亚洲一二三区在线| 午夜日韩激情| 国产一区二区三区视频在线观看| 亚洲欧美国产毛片在线| 久久www免费人成看片高清 | 国产一区二区三区av电影 | 久久三级视频| 欧美成人a视频| 亚洲人成小说网站色在线 | 国产一区二区在线免费观看 | 久久久免费av| 欧美国产日韩一区| 一区二区激情| 国产精品乱码久久久久久| 午夜亚洲激情| 欧美国产在线电影| 一区二区三区免费网站| 国产精品免费aⅴ片在线观看| 亚洲欧美日本另类| 免费观看30秒视频久久| 一本色道久久88精品综合| 欧美天天视频| 久久久久久网址| 99精品视频一区二区三区| 欧美中文字幕精品| 亚洲国产欧美在线| 欧美一区二区高清| 久久夜色精品亚洲噜噜国产mv| 国产精品私拍pans大尺度在线| 亚洲一级一区| 欧美成人有码| 一区二区三区精品视频在线观看| 国产精品色午夜在线观看| 久久精品国产99国产精品| 亚洲高清免费| 久久精品二区三区| 久久久蜜桃精品| 亚洲第一在线视频| 欧美日韩亚洲高清| 亚洲欧美日韩成人| 亚洲激情在线观看| 欧美一区二区在线免费观看| 亚洲国产小视频在线观看| 国产精品免费福利| 欧美国产日本韩| 亚洲精品在线二区| 国产精品狼人久久影院观看方式| 亚洲综合精品四区| 欧美国产成人在线| 欧美一区激情| 一本大道av伊人久久综合| 136国产福利精品导航网址| 国产精品美女| 欧美网站在线| 欧美日韩国产精品专区| 男人天堂欧美日韩|