多多色-多人伦交性欧美在线观看-多人伦精品一区二区三区视频-多色视频-免费黄色视屏网站-免费黄色在线

國內(nèi)最全I(xiàn)T社區(qū)平臺 聯(lián)系我們 | 收藏本站
阿里云優(yōu)惠2
您當(dāng)前位置:首頁 > 互聯(lián)網(wǎng) > Linux daemon進(jìn)程的應(yīng)用、實現(xiàn)和原理

Linux daemon進(jìn)程的應(yīng)用、實現(xiàn)和原理

來源:程序員人生   發(fā)布時間:2015-05-05 08:26:52 閱讀次數(shù):3625次

甚么情況下用daemon進(jìn)程

生產(chǎn)環(huán)境下,除我們ssh登錄上去,然后手動跑的那部份之外,其他都是自動運行的,這些大部份都應(yīng)當(dāng)是后臺履行的。如何才能后臺履行呢?

  1. nohup ./XXX & 
  2. 由系統(tǒng)的其他daemon進(jìn)程啟動。這樣的話,你的程序是它的子進(jìn)程,跟終端沒關(guān)系。退出終端也不會致使進(jìn)程退出。如寫在crontab里。 
  3. 寫成daemon程序,可以手動履行,退出終端時程序不退出。

如何選擇呢?

(1)首先,清算過期日志這1類需求,可以寫1個死循環(huán)1直運行,也能夠?qū)懺赾rontab里,每次履行完就退出(如果每分鐘1次可以滿足的話);

(2)crontab的需要接受最多1分鐘的時延,如果實時性要求更高1些,那末就需要斟酌寫個死循環(huán)了,這個程序可以由crontab來start和restart,只有在掛了重啟時才會出現(xiàn)1分鐘時延;

* * * * * /usr/bin/flock -nx /home/chenming/lock/test1.lock -c '/home/chenming/test1 >/dev/null 2>&1'
(3)服務(wù)不能中斷的(nginx、redis、apache,所有在線服務(wù)),1般都是daemon程序。但理論上用(2)似乎也能夠;固然這二者細(xì)節(jié)上有很多區(qū)分。

怎樣用daemon進(jìn)程

linux C/C++可以直接調(diào)用int daemon(int, int)函數(shù),不需要自己重新實現(xiàn)。示例代碼:

#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <iostream> int main(int argc, char *argv[]) { if (argc < 3) { printf("Usage: $0 no_ch_dir no_close_fd "); exit(0); } int no_ch_dir = atoi(argv[1]); int no_close_fd = atoi(argv[2]); std::cout << "main pid : " << getpid() << std::endl; std::cout << "main parent pid : " << getppid() << std::endl; std::cout << "main pwd : " << get_current_dir_name() << std::endl; if (daemon(no_ch_dir, no_close_fd) != 0) { // 1般都用daemon(0,0) // 成功返回0,失敗返回⑴ // daemon(0,0):chdir到/,關(guān)閉0,1,2描寫符。 std::cout << "stdout: daemon = ⑴" << std::endl; std::cerr << "stderr: daemon = ⑴" << std::endl; return 1; } std::cout << "stdout: daemon = 0" << std::endl; std::cerr << "stderr: daemon = 0" << std::endl; std::cout << "sub pid : " << getpid() << std::endl; std::cout << "sub parent pid : " << getppid() << std::endl; std::cout << "sub pwd : " << get_current_dir_name() << std::endl; while (1); return 0; }

編譯運行:

[chenming@localhost ~]$ g++ test1.cc -o test1 [chenming@localhost ~]$ ./test1 0 0 main pid : 7978 main parent pid : 1382 main pwd : /home/chenming [chenming@localhost ~]$ ps -ef | grep test1 94:chenming 7864 7573 0 16:09 pts/0 00:00:16 vim test1.cc 95:chenming 7897 1 97 16:14 ? 00:33:07 ./test1 0 0 97:chenming 7979 1 47 16:48 ? 00:00:04 ./test1 0 0 99:chenming 7981 1382 8 16:49 pts/1 00:00:00 grep -inE --color test1 [chenming@localhost ~]$ ll /proc/7979/fd total 0 lrwx------. 1 chenming chenming 64 May 1 16:49 0 -> /dev/null lrwx------. 1 chenming chenming 64 May 1 16:49 1 -> /dev/null lrwx------. 1 chenming chenming 64 May 1 16:49 2 -> /dev/null [chenming@localhost ~]$ lsof -p 7979 COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME test1 7979 chenming cwd DIR 253,0 4096 2 / test1 7979 chenming rtd DIR 253,0 4096 2 / test1 7979 chenming txt REG 253,0 8355 142259 /home/chenming/test1 test1 7979 chenming mem REG 253,0 122232 52742 /lib/libgcc_s⑷.4.7⑵0120601.so.1 test1 7979 chenming mem REG 253,0 142600 38788 /lib/ld⑵.12.so test1 7979 chenming mem REG 253,0 1906308 38865 /lib/libc⑵.12.so test1 7979 chenming mem REG 253,0 202040 47921 /lib/libm⑵.12.so test1 7979 chenming mem REG 253,0 942040 52866 /usr/lib/libstdc++.so.6.0.13 test1 7979 chenming 0u CHR 1,3 0t0 3903 /dev/null test1 7979 chenming 1u CHR 1,3 0t0 3903 /dev/null test1 7979 chenming 2u CHR 1,3 0t0 3903 /dev/null

man 3 daemon可以查看到函數(shù)簽名:

#include <unistd.h>

int daemon(int nochdir, int noclose);

怎樣寫daemon進(jìn)程

1.fork,父進(jìn)程退出

2.setsid。跟終端脫離關(guān)系。

3.umask、關(guān)掉0,1,2文件描寫符。

4.chdir

5.信號處理

這里只有1和 2是必須的。31般都會做;5大部份不做。

自己實現(xiàn)1個:

#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <iostream> #include <sys/types.h> #include <sys/stat.h> int daem(int no_ch_dir, int no_close_fd) { int pid = fork(); if (pid < 0) { return ⑴; }else if (pid > 0){ exit(0); } if (setsid() < 0) { return ⑴; } if (no_ch_dir == 0) { chdir("/"); } umask(0); if (no_close_fd == 0) { close(0); close(1); close(2); } return 0; }

redis的實現(xiàn):

void daemonize(void) { int fd; if (fork() != 0) exit(0); /* parent exits */ setsid(); /* create a new session */ /* Every output goes to /dev/null. If Redis is daemonized but * the 'logfile' is set to 'stdout' in the configuration file * it will not log at all. */ if ((fd = open("/dev/null", O_RDWR, 0)) != ⑴) { dup2(fd, STDIN_FILENO); dup2(fd, STDOUT_FILENO); dup2(fd, STDERR_FILENO); if (fd > STDERR_FILENO) close(fd); } }


memcached的實現(xiàn):

#include <fcntl.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include "memcached.h" int daemonize(int nochdir, int noclose) { int fd; switch (fork()) { case ⑴: return (⑴); case 0: break; default: _exit(EXIT_SUCCESS); } if (setsid() == ⑴) return (⑴); if (nochdir == 0) { if(chdir("/") != 0) { perror("chdir"); return (⑴); } } if (noclose == 0 && (fd = open("/dev/null", O_RDWR, 0)) != ⑴) { if(dup2(fd, STDIN_FILENO) < 0) { perror("dup2 stdin"); return (⑴); } if(dup2(fd, STDOUT_FILENO) < 0) { perror("dup2 stdout"); return (⑴); } if(dup2(fd, STDERR_FILENO) < 0) { perror("dup2 stderr"); return (⑴); } if (fd > STDERR_FILENO) { if(close(fd) < 0) { perror("close"); return (⑴); } } } return (0); }

nginx的實現(xiàn):

#include <ngx_config.h> #include <ngx_core.h> ngx_int_t ngx_daemon(ngx_log_t *log) { int fd; switch (fork()) { case ⑴: ngx_log_error(NGX_LOG_EMERG, log, ngx_errno, "fork() failed"); return NGX_ERROR; case 0: break; default: exit(0); } ngx_pid = ngx_getpid(); if (setsid() == ⑴) { ngx_log_error(NGX_LOG_EMERG, log, ngx_errno, "setsid() failed"); return NGX_ERROR; } umask(0); fd = open("/dev/null", O_RDWR); if (fd == ⑴) { ngx_log_error(NGX_LOG_EMERG, log, ngx_errno, "open("/dev/null") failed"); return NGX_ERROR; } if (dup2(fd, STDIN_FILENO) == ⑴) { ngx_log_error(NGX_LOG_EMERG, log, ngx_errno, "dup2(STDIN) failed"); return NGX_ERROR; } if (dup2(fd, STDOUT_FILENO) == ⑴) { ngx_log_error(NGX_LOG_EMERG, log, ngx_errno, "dup2(STDOUT) failed"); return NGX_ERROR; } #if 0 if (dup2(fd, STDERR_FILENO) == ⑴) { ngx_log_error(NGX_LOG_EMERG, log, ngx_errno, "dup2(STDERR) failed"); return NGX_ERROR; } #endif if (fd > STDERR_FILENO) { if (close(fd) == ⑴) { ngx_log_error(NGX_LOG_EMERG, log, ngx_errno, "close() failed"); return NGX_ERROR; } } return NGX_OK; }




生活不易,碼農(nóng)辛苦
如果您覺得本網(wǎng)站對您的學(xué)習(xí)有所幫助,可以手機(jī)掃描二維碼進(jìn)行捐贈
程序員人生
------分隔線----------------------------
分享到:
------分隔線----------------------------
關(guān)閉
程序員人生
主站蜘蛛池模板: 成人伊人网 | 久久avav| freexxxhd性欧美 | 日本成在线人视频免费视频 | 日本一级淫片免费放 | 中文乱码一二三四有限公司 | 久久七国产精品 | 男人边吃奶边做性视频 | 日本一区二区三区免费高清在线 | 久久精品国产99久久久 | 在线观看美女网站 | 免费国产成人高清在线观看不卡 | 国产精品极品美女免费观看 | 亚洲欧美一 | 性欧美欧美 | 日韩天堂 | videoa性欧美| 午夜视频免费 | 欧美日一级 | 五月婷婷在线观看视频 | 欧美日韩中文亚洲v在线综合 | 亚洲视频区 | 久久精品国产欧美成人 | 性色xxx视频 | 久久99精品久久久久久三级 | 日本zzzwww大片免费 | 久久精品9 | 国产欧美日韩精品a在线观看 | 一二三四免费手机在线观看视频 | 国产欧美自拍视频 | 欧美性一区二区三区 | 欧美日韩激情一区二区三区 | 在线视频播放网站 | 九九九久久久 | 亚洲成人在线免费观看 | 亚洲高清在线观看播放 | 一二三四视频免费观看在线看1 | 老司机午夜免费视频 | 中文字幕乱码中文乱码综合 | 俺也来俺也去俺也射 | 亚洲第一福利网站 |