守護進程的概念和創建步驟

在這裏插入圖片描述

1. 進程組

也稱之爲作業。進程組ID等於第一個進程ID,因此可以通過進程ID是否等於進程組ID來判斷該進程是不是進程組的組長。

只要進程組中有一個進程存在,進程組就存在,哪怕組長已經沒了。

一個進程可以爲自己或子進程設置進程組ID

2. 會話

由多個進程組組成。
創建會話要注意以下5點:

  1. 調用進程不能是進程組組長,該進程變成新會話首進程(session header)
  2. 該進程成爲一個新進程組的組長進程。
  3. 新會話丟棄原有的控制終端,該會話沒有控制終端。
  4. 該調用進程是組長進程,則出錯返回。
  5. 建立新會話時,先調動fork,父進程終止,子進程調用setsid(setsid後子進程不受終端影響,終端退出,不影響子進程)。
man 2 setsid

在這裏插入圖片描述

3. 守護進程

守護進程常常以“d”結尾
在這裏插入圖片描述

3.1 創建守護進程模型

創建守護進程最關鍵的一步就是調用setsid函數創建一個新的Session,併成爲Session Leader

  1. 創建子進程,父進程退出
    所有工作在子進程中進行,形式上脫離了控制終端
  2. 在子進程中創建新會話
    setsid()函數
    使子進程完全獨立出來,脫離控制
  3. 改變當前目錄爲根目錄
    chdir()函數
    防止佔用可卸載的文件系統
    也可以換成其他路徑
  4. 重設文件權限掩碼
    umask()函數
    防止繼承的文件創建屏蔽字拒絕某些權限
    增加守護進程的靈活性
  5. 關閉文件描述符
  6. 開始執行守護進程核心工作
  7. 守護進程退出處理程序模型

其中,3、4、5步不必要

3.2 守護進程的步驟

  1. 創建子進程fork
  2. 父進程退出
  3. 子進程當會長setsid
  4. 切換工作目錄$HOME
  5. 設置掩碼umask
  6. 關閉文件描述符0,1,2,爲了避免浪費資源
  7. 執行核心邏輯

3.3 創建一個守護進程實例:每份中在$HOME/log/ 創建一個文件 ,文件名—— 程序名.時間戳

#include<stdio.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<string.h>
#include<stdlib.h>
#include<signal.h>
#include<sys/time.h>
#include<time.h>
 
//通過宏定義文件名
#define _FILE_NAME_FORMAT_ "%s/log/mydaemon.%ld" //定義文件格式化
 
void touchfile(int num){
	//獲取家目錄
	char *HomeDir=getenv("HOME");
	char strFilename[250]={0};
	//獲取時間戳的函數
	//time(NULL);
	sprintf(strFilename, _FILE_NAME_FORMAT_, HomeDir, time(NULL));
 
	int fd=open(strFilename, O_RDWR|O_CREAT, 0666);
	//文件打開失敗
	if(fd<0){
		perror("open err");
		exit(1);
	}
	close(fd);
}
 
int main(){
	//創建守護進程的步驟如下
	//創建子進程,父進程退出
	pid_t pid=fork();
	if(pid>0){
		exit(1);
	}
	//當會長
	setsid();
	//設置掩碼
	umask(0);
	//切換目錄
	//getenv獲取環境變量
	chdir(getenv("HOME"));//切換到家目錄
	//關閉文件描述符(一般通過測試之後,纔會關閉文件描述符)
	//close(0),close(1),close(2)
 
	//執行核心邏輯
	//設置一個定時器——每60秒來一次
	struct itimerval myit={{60,0},{60,0}};
	setitimer(ITIMER_REAL, &myit, NULL);
	//註冊捕獲函數
	struct sigaction act;
	act.sa_flags=0;
	//清空阻塞信號集
	sigemptyset(&act.sa_mask);
	//綁定捕獲函數
	act.sa_handler=touchfile;
	//註冊捕獲函數
	sigaction(SIGALRM, &act, NULL);
	while(1){
		//每隔一分鐘在/home/itheima/log創建文件
		sleep(1);
	}
	
	return 0;
}

3.4 nohup指令

指令nohup去執行進程就不會收到第一個信號
在這裏插入圖片描述
通過nohup指令也可以達到守護進程的創建效果。(可以把進程輸出重定向到特定的地方)

  • nohup 指令會讓cmd收不到SIGHUP信號
  • & 代表後臺運行

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章