日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > linux >内容正文

linux

Linux进程实践(5) --守护进程

發布時間:2025/3/17 linux 17 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Linux进程实践(5) --守护进程 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

概述

? ?守護進程是在需要在后臺長期運行不受終端控制的進程,通常情況下守護進程在系統啟動時自動運行,在服務器關閉的時候自動關閉;守護進程的名稱通常以d結尾,比如sshd、xinetd、crond、atd等。


守護進程編程規則?

? ?調用umask將文件模式創建屏蔽字設置為一個已知值(通常是0)

? ?調用fork(),創建新進程,它會是將來的守護進程

? ?然后使父進程exit,保證子進程不是進程組組長

? ?調用setsid創建新的會話

? ?? ?會話:是一個或者多個進程組的集合,通常一個會話開始與用戶登錄,終止于用戶退出。在此期間,該用戶運行的所有進程都屬于這個會話期。

? ?將進程的當前目錄改為根目錄?(如果把當前目錄作為守護進程的目錄,當前目錄不能被卸載,它作為守護進程的工作目錄了。)

? ?關閉不再需要的文件描述符

? ?將標準輸入、標準輸出、標準錯誤重定向到/dev/null

setsid

pid_t setsid(void);

?setsid()?creates?a?new?session?if?the?calling?process?is?not?a?process?group?leader.??The?calling?process?is?the?leader?of?the?new?session,?the?process?group??leader??of??the??new?process??group,??and?has?no?controlling?terminal.??The?process?group?ID?and?session?ID?of?the?calling?process?are?set?to?the?PID?of?the?calling?process.??The?calling?process??will?be?the?only?process?in?this?new?process?group?and?in?this?new?session.

/*當調用進程不是一個進程組的組長時,Setsid創建一個新的會話;調用者進程會是這個會話期唯一的一個進程,且是該進程組的組長;調用者進程id是組id,也是會話期的id。不能用進程組組長去調用setsid函數*/

//示例: int main() {pid_t pid = fork();if (pid == -1)err_exit("fork error");else if (pid != 0)exit(EXIT_SUCCESS);// //查看下面這一部分代碼在注釋的前后有什么變化 // pid_t id = setsid(); // if (id == -1) // err_exit("setsid error"); // else // cout << "new session id = " << id << endl;cout << "getpid = " << getpid() << endl;cout << "getpgid = " << getpgid(getpid()) << endl;return 0; }

RETURN?VALUE

???????On??success,??the??(new)??session??ID??of??the??calling??process??is?returned.??On?error,?(pid_t)?-1?is?returned,?and?errno?is?set?to?indicate?the?error.

Linux中的守護進程API

int daemon(int nochdir, int noclose);

參數:

? ?nochdir:=0將當前目錄更改至“/”

? ?noclose:=0將標準輸入、標準輸出、標準錯誤重定向至“/dev/null”

DESCRIPTION

???????The??daemon()??function?is?for?programs?wishing?to?detach?themselves?from?the?controlling?terminal?and?run?in?the?background?as?system?daemons.?If?nochdir?is?zero,?daemon()?changes?the?calling?process's?current?working??directory??to?the?root?directory?("/");?otherwise,?the?current?working?directory?is?left?unchanged.?If?noclose?is?zero,?daemon()?redirects?standard?input,?standard?output?and?standard?error?to?/dev/null;?otherwise,?no?changes?are?made?to?these?file?descriptors.

//示例:自己動手寫daemon函數(一個比較簡單的示例) bool myDaemon(bool nochdir, bool noclose) {umask(0);pid_t pid = fork();if (pid == -1)err_exit("fork error");else if (pid != 0) //parentexit(0);setsid();if (nochdir == 0)chdir("/");if (noclose == 0){int i;for (i=0; i < 3; ++i)close(i);open("/dev/null", O_RDWR); //相當于把0號文件描述符指向/dev/nulldup(0); //把0號文件描述符 賦值給空閑的文件描述符 1dup(0); //把0號文件描述符 賦值給空閑的文件描述符 2}return true; }//測試 int main(int argc, char *argv[]) {myDaemon(0, 0); //0表示做出改變(當前目錄,文件描述符),1表示不改變printf("test ...\n");while (true){sleep(1);}return 0; }

//一個比較經典和完善的實例;來自《APUE》 #include "apue.h" #include <syslog.h> #include <fcntl.h> #include <sys/resource.h>bool myDaemon(const char *cmd);int main(int argc, char *argv[]) {myDaemon("xiaofang");while (true){sleep(1);}return 0; }bool myDaemon(const char *cmd) {umask(0);//Get maximum number of file descriptors.rlimit rlt;if (getrlimit(RLIMIT_NOFILE,&rlt) < 0){err_quit("%s: can't get file limit",cmd);}//Become a session leader to lose controlling TTY.pid_t pid = fork();if (pid == -1){err_quit("%s: can't fork",cmd);}if (pid != 0) //parent{exit(0);}setsid();//Ensure future opens won't allocate controlling TTYs.struct sigaction sa;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",cmd);}if ((pid = fork()) < 0){err_quit("%s: can't fork",cmd);}else if (pid != 0) //Second Parent{exit(EXIT_SUCCESS);}//change the current working directory to the rootif (chdir("/") < 0){err_quit("%s: can't change directory to /",cmd);}//close all open file descriptionif (rlt.rlim_max == RLIM_INFINITY){rlt.rlim_max = 1024;}for (unsigned int i = 0; i < rlt.rlim_max; ++i){close(i);}//Attach file descriptors 0, 1, and 2 to /dev/null.int fd0 = open("/dev/null",O_RDWR);int fd1 = dup(0);int fd2 = dup(0);//Initialize the log file.openlog(cmd,LOG_CONS,LOG_DAEMON);if (fd0 != 0 || fd1 != 0 || fd2 != 0){syslog(LOG_ERR,"unexpected file descriptors %d %d %d",fd0,fd1,fd2);exit(EXIT_FAILURE);}return true; }

總結

以上是生活随笔為你收集整理的Linux进程实践(5) --守护进程的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。