建立一個守護進程 ,使用 Linux 信號機制,讓守護進程退出。linux
代碼/************************************************************************* > File Name: main.c > Author: 楊永利 > Mail: 1795018360@qq.com > Created Time: 2021年07月16日 星期五 18時38分59秒 ************************************************************************/ #include <unistd.h> #include <signal.h> #include <sys/types.h> #include <sys/stat.h> #include <stdio.h> #include <stdlib.h> #define MAXFILE 3 // 建立守護進程 void init_daemon(void) { pid_t pid = 0; int i = 0; // 第一次 fork,使之成爲守護進程 pid = fork(); if (pid < 0) { // 判斷返回值,fork 函數出錯 perror("fork error."); exit(1); } else if (pid > 0) { // 父進程,退出 exit(0); } // 子進程 // 使子進程成爲新的會話組長和進程組長,擺脫原會話控制,,擺脫原進程組控制, 擺脫控制終端控制 setsid(); // 改變工做目錄,防止其餘緣由 ,致使工做目錄不存在 // 第二次 fork, pid = fork(); if (pid < 0) { // 判斷返回值,fork 函數出錯 perror("fork error."); exit(1); } else if (pid > 0) { // 父進程,退出 exit(0); } //關閉打開的文件描述符,避免資源浪費 for (i = 0; i < MAXFILE; ++i) { // close(i); } chdir("/"); // 重設文件權限掩碼 umask(0); return; } void mysighandler_t(int arg) { printf("收到信號 SIGUSR1 系統開始退出 \n"); exit(1); } int main(int argc, char const *argv[]) { // 註冊一個信號 : 告訴 linux 內核 當有信號 SIGUSR1 發給個人時候 , 請你調用這個 apimysighandler_t signal(SIGUSR1, mysighandler_t); //建立守護進程 init_daemon(); printf("守護進程啓動...\n"); while (1) { sleep(5); printf("程序正在後臺運行...\n"); } return 0; }知識回顧
守護進程:Daemon(精靈)進程,是 Linux 中的後臺服務進程,一般獨立於控制終端而且週期性地執行某種任務或等待處理某些發生的事件。通常採用以 d 結尾的名字。api
setsid()
函數,使子進程徹底獨立出來,脫離控制。chdir()
函數,防止佔用可卸載的文件系統,也能夠換成其它路徑。umask()
函數,防止繼承的文件建立屏蔽字拒絕某些權限,增長守護進程靈活性。信號:是進程間通訊(IPC)方式之一。網絡
A 給 B 發送信號,B 收到信號以前執行本身的代碼,收到信號後,無論執行到程序的什麼位置,都要暫停運行,去處理信號,處理完畢再繼續執行。與硬件中斷相似——異步模式。但信號是軟件層面上實現的中斷,早期常被稱爲「軟中斷」。異步
每一個進程收到的全部信號,都是由內核負責發送的。socket
信號名稱 | 信號說明 | 默認處理 |
---|---|---|
SIGABRT | 由程序調用 abort時產生該信號。 程序異常結束。 | 進程終止而且產生core文件 |
SIGALRM | timer到期, 有alarm或者setitimer | 進程終止 |
SIGBUS | 總線錯誤,地址沒對齊等。取決於具體硬件。 | 結束終止併產生core文件 |
SIGCHLD | 進程中止或者終止時,父進程會收到該信號。 | 忽略該信號 |
SIGCONT | 讓中止的進程繼續執行 | 繼續執行或者忽略 |
SIGFPE | 算術運算異常,除0等。 | 進程終止而且產生core文件。 |
SIGHUP | 終端關閉時產生這個信號 | 進程終止 |
SIGILL | 代碼中有非法指令 | 進程終止併產生core文件 |
SIGINT | 終端輸入了中斷字符ctrl+c | 進程終止 |
SIGIO | 異步I/O,跟SIGPOLL同樣。 | 進程終止 |
SIGIOT | 執行I/O時產生硬件錯誤 | 進程終止而且產生core文件 |
SIGKILL | 這個信號用戶不能去捕捉它。 | 進程終止 |
SIGPIPE | 往管道寫時,讀者已經不在了,或者往一個已斷開數據流socket寫數據。 | 進程終止 |
SIGPOLL | 異步I/O,跟SIGIO同樣。 | 進程終止 |
SIGPROF | 有setitimer設置的timer到期引起 。 | 進程終止 |
SIGPWR | Ups電源切換時 | 進程終止 |
SIGQUIT | Ctrl+\,不一樣於SIGINT,這個是會產生core dump文件的。 | 進程終止而且產生core文件 |
SIGSEGV | 內存非法訪問,默認打印出segment fault | 進程終止而且產生core文件 |
SIGSTOP | 某個進程中止執行,該信號不能被用戶捕捉。 | 進程暫停執行 |
SIGSYS | 調用操做系統不認識的系統調用。 | 進程終止而且產生core文件 |
SIGTERM | 有kill函數調用產生。 | 進程終止 |
SIGTRAP | 有調試器使用,gdb | 進程終止而且產生core文件 |
SIGTSTP | Ctrl+z,掛起進程。 | 進程暫停 |
SIGTTIN | 後臺程序要從終端讀取成數據時。 | 進程暫停 |
SIGTTOU | 後臺終端要把數據寫到終端時。 | 進程暫停 |
SIGURG | 一些緊急的事件,好比從網絡收到帶外數據。 | 忽略 |
SIGUSR1 | 用戶自定義信號 | 進程終止 |
SIGUSR2 | 用戶自定義信號 | 進程終止 |
SIGVTALRM | 有setitimer產生。 | 進程終止 |