守護進程
-
會話: 進程組的更高一級,多個進程對應一個會話。
-
進程組: 多個進程在同一個組,第一個進程默認時進程組的組長,創建會話的時候,組長不可以創建,必須是組員創建
-
創建會話的步驟:創建子進程,父進程去死,子進程自當會長
-
守護進程的步驟
- 創建子進程fork
- 父進程退出
- 子進程當會長 setsid
- 切換工作目錄 $HOME
- 設置掩碼 umask
- 處理SIGCHLD信號
- 如果屏蔽了SIGCHLD信號,內核會把僵屍子進程轉交給init進程處理 signal(SIGCHLD, SIG_IGN);
- 處理SIGCHLD信號
- 關閉文件描述符0,1,2為了避免浪費資源
- 執行核心邏輯
- 退出
-
通過nohup指令也可以達到守護進程創建的效果
- 例:nohup cmd [> 1.log] &
- nohup指令會讓cmd收不到SIGHUP信號
- & 代表后台運行
void sigCatchFun(int num)
{
char *HomeDir = getenv("HOME");
char strFileName[256]={0};
sprintf(strFileName,_FILE_NAME_FORMAT_,HomeDir,time(NULL));
int fd = open(strFileName,O_WRONLY|O_CREAT,0666);
if(fd < 0)
{
perror("open err\n");
exit(-1);
}
close(fd);
}
int main()
{
//創建子進程
pid_t pid = 0;
pid=fork();
if(pid > 0)
//父進程退出
exit(1);
//子進程當會長
setsid();
//設置掩碼 子進程從其父進程繼承的文件的權限掩碼,可能會修改守護進程所創建的文件權限,需要將掩碼清楚。
umask(0);
//切換工作目錄
chdir(getenv("HOME"));
//關閉文件描述符
//close(1),close(0),close(2)
//執行核心邏輯
// 自定義定時器 #include <sys/time.h>
//struct itimerval oldSendSig,sendSig={{60,0},{60,0}};
struct itimerval oldSendSig,sendSig={{60,0},{1,0}};
setitimer(ITIMER_REAL,&sendSig,&oldSendSig);
//注冊捕捉函數 #include <signal.h>
struct sigaction act;
act.sa_flags=0;
act.sa_handler = sigCatchFun;
sigemptyset(&act.sa_mask);
//sigaddset(&%1.sa_mask,SIGINT);
sigaction(SIGALRM,&act,NULL);
while(1)
//每隔一分鍾在$PATH/log下創建文件
sleep(1);
//退出
return 0;
}
