網站后臺無法審核怎么把網站排名排上去
目錄
守護進程
前臺進程? 后臺進程
session(進程會話)
前臺任務和后臺任務比較好
本質
繪畫和終端都關掉了,那些任務仍然在
bash也退了,然后就托孤了
?編輯
守護進程化---不想受到任何用戶登陸和注銷的影響?編輯
如何做到(setsid)(創(chuàng)建新會話)
怎么保證自己不是組長
守護進程本質(孤兒進程)
守護進程忽略的幾個信號和含義
1.?SIGHUP (Hangup signal)
2.?SIGINT (Interrupt signal)
3.?SIGTERM (Termination signal)
4.?SIGQUIT (Quit signal)
5.?SIGCHLD (Child terminated signal)
6.?SIGPIPE (Broken pipe signal)
為什么守護進程忽略這些信號?
如何在 C/C++ 中忽略信號?
總結:
代碼
網絡服務器以守護進程運行
/dev/null,垃圾桶
dup2重定向到/dev/null
??編輯
測試:啟動后直接終止了,變成后臺了
檢查是否起來了netstat -nltp
ps ajx |head -1 && ps ajx |grep tcpserver?
?查看工作目錄ls /proc/644717 -l
?編輯
ls /proc/644717/fd -l
?編輯
把xshell關閉了,服務仍然在
再打開一個xshell就等于重新啟動一個會話,還能看到tcpserver進程在運行
?編輯
更改目錄到根目錄
?編輯
把服務器進程關閉掉kill -9 PID
把打印的放進日志文件
守護進程函數daemon,上面的是模擬
daemon()?函數的定義
參數:
返回值:
daemon()?的作用
守護進程的常見步驟
使用?daemon()?示例
代碼解析:
daemon()?與?setsid()?和?fork()?的比較
使用守護進程時的注意事項
總結
守護進程
前臺進程? 后臺進程
后臺進程不能標準輸入
3個后臺進程了
把2號任務提到前臺進程
ctrl c終止前臺進程
把任務提到前臺進程,后悔了,再重新放回后臺
ctrl z就可以暫停,然后系統(tǒng)自動把bash提到前臺
bg 3再把3號進程啟動起來
session(進程會話)
在Linux中,session
(會話)通常指的是與用戶交互的一個環(huán)境,它是系統(tǒng)中與某個用戶交互的一系列活動的集合。會話在Linux系統(tǒng)中有多種用途,下面是幾種常見的會話類型及其相關概念:
1.?登錄會話(Login Session)
當用戶通過登錄界面(如終端或圖形界面)登錄到系統(tǒng)時,系統(tǒng)會為該用戶創(chuàng)建一個會話。登錄會話包括:
-
用戶身份驗證(通過用戶名和密碼等方式)。
-
運行用戶的默認Shell(例如
bash
)。 -
用戶環(huán)境變量的設置(例如
$PATH
、$HOME
等)。
這種會話通常由登錄管理器(如login
、sshd
或gdm
等)管理。當用戶退出登錄時,該會話會結束。
2.?進程會話(Process Session)
在Linux中,每個進程都有一個會話(Session),這個會話由session leader
(會話領導進程)控制。進程會話的特征包括:
-
每個進程在啟動時都會被分配一個會話ID。
-
會話通常由一個進程創(chuàng)建,稱為會話領導進程。
-
會話通常用于進程組管理,特別是在控制終端和后臺進程之間的交互。
會話的管理由setsid()
系統(tǒng)調用進行,當進程調用setsid()
時,它會創(chuàng)建一個新的會話,并成為該會話的領導進程
前臺任務和后臺任務比較好
本質
任務里有多個進程組
每多建一個就多一個
繪畫和終端都關掉了,那些任務仍然在
bash也退了,然后就托孤了
受到了用戶登錄和退出的影響
守護進程化---不想受到任何用戶登陸和注銷的影響
如何做到(setsid)(創(chuàng)建新會話)
怎么保證自己不是組長
守護進程本質(孤兒進程)
守護進程忽略的幾個信號和含義
在 C/C++ 中,守護進程通常會忽略一些信號,確保其在后臺繼續(xù)運行,而不被用戶的操作或其他系統(tǒng)事件干擾。除了常見的信號外,SIGPIPE
?也是一個重要的信號,守護進程通常會忽略它。以下是幾個常見的守護進程忽略的信號及其作用,包括?SIGPIPE
:
1.?SIGHUP (Hangup signal)
- 作用:最初用于通知進程,終端連接已經斷開。對于守護進程來說,接收到 SIGHUP 信號通常意味著該進程應重新加載其配置文件。
- 守護進程行為:守護進程通常會忽略 SIGHUP 信號,這樣即使終端連接斷開,進程也會繼續(xù)運行。
2.?SIGINT (Interrupt signal)
- 作用:通常由用戶通過鍵盤操作(Ctrl+C)發(fā)送,用來中斷進程的執(zhí)行。
- 守護進程行為:守護進程會忽略 SIGINT 信號,避免被用戶的鍵盤中斷。
3.?SIGTERM (Termination signal)
- 作用:請求進程終止的信號。系統(tǒng)或其他進程通常會發(fā)送此信號來請求進程優(yōu)雅地結束。
- 守護進程行為:盡管守護進程有時會捕獲 SIGTERM 信號并優(yōu)雅地退出,但它也可能選擇忽略該信號,或者采取一些特定的清理操作后繼續(xù)運行。
4.?SIGQUIT (Quit signal)
- 作用:通常由用戶通過 Ctrl+\ 發(fā)送,用來終止進程并生成核心轉儲文件。
- 守護進程行為:守護進程通常會忽略 SIGQUIT 信號,以避免被意外終止并生成不必要的核心轉儲文件。
5.?SIGCHLD (Child terminated signal)
- 作用:當子進程結束時,父進程會收到 SIGCHLD 信號,通常用于處理子進程的退出狀態(tài)。
- 守護進程行為:守護進程可能會忽略 SIGCHLD 信號,特別是當它不需要對子進程的退出狀態(tài)進行處理時。
6.?SIGPIPE (Broken pipe signal)
- 作用:當一個進程向一個已經關閉的管道或套接字寫入數據時,操作系統(tǒng)會發(fā)送 SIGPIPE 信號給該進程。
- 守護進程行為:守護進程通常會忽略 SIGPIPE 信號。這是因為如果進程嘗試向一個已經關閉的管道或套接字寫入數據,默認情況下會導致進程終止。通過忽略 SIGPIPE 信號,守護進程可以避免因意外的關閉管道而終止,通常這種情況下進程會返回一個錯誤代碼,而不是被強制終止。
為什么守護進程忽略這些信號?
守護進程的設計目標是長時間穩(wěn)定地在后臺運行,因此它們通常需要避免因為用戶的操作(如 Ctrl+C)、系統(tǒng)的請求(如終止信號)或其他不必要的信號而中斷。忽略這些信號有助于確保進程不被意外終止,可以持續(xù)運行。
如何在 C/C++ 中忽略信號?
在 C/C++ 中,您可以使用?signal()
?函數來捕獲或忽略信號。若要忽略一個信號,可以將信號處理程序設置為?SIG_IGN
。例如:
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>int main() {// 忽略 SIGHUP, SIGINT, SIGPIPEsignal(SIGHUP, SIG_IGN); // 忽略 SIGHUPsignal(SIGINT, SIG_IGN); // 忽略 SIGINTsignal(SIGPIPE, SIG_IGN); // 忽略 SIGPIPE// 守護進程的邏輯while (1) {// 模擬工作sleep(1);}return 0;
}
總結:
- SIGHUP: 通常用于通知終端連接斷開,守護進程會忽略它。
- SIGINT: 用戶通過 Ctrl+C 發(fā)送的中斷信號,守護進程會忽略它。
- SIGTERM: 請求進程終止,守護進程有時會忽略它,或者捕獲后進行清理操作。
- SIGQUIT: 用戶通過 Ctrl+\ 發(fā)送的信號,守護進程會忽略它。
- SIGCHLD: 子進程退出時發(fā)送的信號,守護進程可能會忽略它。
- SIGPIPE: 管道或套接字關閉時發(fā)送的信號,守護進程會忽略它,避免進程被意外終止。
通過忽略這些信號,守護進程能夠在后臺穩(wěn)定運行,避免不必要的中斷或退出。
代碼
先忽略幾個常見信號
#pragma once
#include<iostream>
#include<cstdlib>
#include<unistd.h>
#include<signal.h>
#include<string>using namespace std;void Daemon(const string &cwd = "")
{//1.忽略其他異常信號signal(SIGCLD, SIG_IGN);signal(SIGPIPE, SIG_IGN);signal(SIGSTOP, SIG_IGN);//2.將自己變成獨立的會話if(fork() > 0){exit(0);}setsid();//3.g更改當前目錄if(!cwd.empty()){chdir(cwd.c_str());//更改當前目錄}}
網絡服務器以守護進程運行
/dev/null,垃圾桶
dup2重定向到/dev/null
?
Daemon.hpp
#pragma once
#include <iostream>
#include <cstdlib>
#include <unistd.h>
#include <signal.h>
#include <string>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
using namespace std;const string nullfile = "/dev/null";void Daemon(const string &cwd = "")
{// 1.忽略其他異常信號signal(SIGCLD, SIG_IGN);signal(SIGPIPE, SIG_IGN);signal(SIGSTOP, SIG_IGN);// 2.將自己變成獨立的會話if (fork() > 0){exit(0);}setsid();// 3.g更改當前目錄if (!cwd.empty()){chdir(cwd.c_str()); // 更改當前目錄}// 4.有打印的,標準輸出標準輸入的,所以要把表示輸入,標準輸出,標準錯誤重定向至/dev/null// 標準錯誤一般要打印到日志文件,不要打印到屏幕int fd = open(nullfile.c_str(), O_RDWR);//讀寫方式打開if(fd > 0){dup2(fd, 0);dup2(fd, 1);dup2(fd, 2);close(fd);}}
測試:啟動后直接終止了,變成后臺了
檢查是否起來了netstat -nltp
ps ajx |head -1 && ps ajx |grep tcpserver?
自成進程組,自成會話
?查看工作目錄ls /proc/644717 -l
還在當前目錄
ls /proc/644717/fd -l
把xshell關閉了,服務仍然在
再打開一個xshell就等于重新啟動一個會話,還能看到tcpserver進程在運行
更改目錄到根目錄
把服務器進程關閉掉kill -9 PID
把打印的放進日志文件
守護進程函數daemon,上面的是模擬
在 C/C++ 中,daemon()
?函數用于創(chuàng)建守護進程(daemon)。守護進程通常是系統(tǒng)后臺運行的進程,通常沒有控制終端,并且可以在系統(tǒng)啟動時自動啟動或在用戶退出登錄時保持運行。守護進程會與控制終端斷開連接,通常用于執(zhí)行長期運行的任務。
daemon()
?函數的定義
daemon()
?函數通常在?<unistd.h>
?中聲明,原型如下:
#include <unistd.h>int daemon(int nochdir, int noclose);
參數:
nochdir
: 如果設置為?0
,守護進程將在啟動時改變當前工作目錄為根目錄(/
)。這是因為守護進程一般不希望占用當前工作目錄,并防止在程序退出時當前工作目錄被鎖定。如果設置為?1
,則守護進程的當前工作目錄不會改變。noclose
: 如果設置為?0
,守護進程會關閉標準輸入、標準輸出和標準錯誤輸出(stdin
,?stdout
,?stderr
)。通常這是守護進程的行為,以防它繼續(xù)與終端交互。如果設置為?1
,守護進程將不會關閉這些文件描述符。
返回值:
- 成功時,返回?
0
。 - 出錯時,返回?
-1
,并將?errno
?設置為具體的錯誤值。
daemon()
?的作用
daemon()
?函數執(zhí)行以下操作:
- 分離進程:它使進程脫離控制終端,成為一個守護進程。
- 改變工作目錄:它將工作目錄切換到根目錄?
/
,以確保守護進程不會阻止文件系統(tǒng)的卸載。 - 關閉文件描述符:它關閉進程的標準輸入、標準輸出和標準錯誤輸出,通常會將這些文件描述符重定向到某個日志文件或?
/dev/null
。
守護進程的常見步驟
通常,守護進程的創(chuàng)建步驟包括:
- 調用?
fork()
?創(chuàng)建子進程,父進程退出。 - 調用?
setsid()
?創(chuàng)建新會話并脫離終端。 - 調用?
daemon()
?或手動設置工作目錄并關閉文件描述符。
使用?daemon()
?示例
下面是一個簡單的 C 程序示例,演示如何使用?daemon()
?創(chuàng)建守護進程:
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>int main() {// 調用 daemon() 創(chuàng)建守護進程if (daemon(0, 0) == -1) {perror("daemon failed");exit(EXIT_FAILURE);}// 守護進程在后臺執(zhí)行任務while (1) {// 模擬后臺任務// 這里可以執(zhí)行長期運行的任務,如定時備份、日志記錄等sleep(60); // 每分鐘執(zhí)行一次}return 0;
}
代碼解析:
daemon(0, 0)
:將守護進程從終端脫離,改變當前工作目錄到根目錄,并關閉標準輸入、標準輸出和標準錯誤輸出。這個調用會將進程轉為守護進程。sleep(60)
:模擬守護進程在后臺執(zhí)行任務,每分鐘執(zhí)行一次。
daemon()
?與?setsid()
?和?fork()
?的比較
在手動創(chuàng)建守護進程時,通常會使用?fork()
?和?setsid()
?來脫離終端并創(chuàng)建一個新的會話。然而,daemon()
?函數將這些步驟封裝在一個調用中,因此可以更方便地創(chuàng)建守護進程?;旧?#xff0c;daemon()
?做了以下幾件事:
- 創(chuàng)建一個子進程,父進程退出。
- 調用?
setsid()
?創(chuàng)建新會話并使進程脫離終端。 - 改變工作目錄到根目錄。
- 關閉標準輸入、輸出、錯誤輸出。
使用守護進程時的注意事項
- 文件描述符:守護進程會關閉標準輸入、標準輸出和標準錯誤輸出,因此在守護進程中通常需要將這些描述符重定向到?
/dev/null
?或某個日志文件。 - 退出狀態(tài):守護進程通常是長期運行的,退出時要考慮清理工作,如關閉打開的文件、釋放資源等。
- 進程管理:可以使用進程管理工具如?
systemd
?或?init.d
?來啟動和管理守護進程。
總結
daemon()
?是一個用于創(chuàng)建守護進程的方便函數,它將一些常見的守護進程設置封裝在一起。- 它脫離控制終端、改變工作目錄為根目錄、關閉標準輸入輸出等,使得進程成為一個后臺獨立運行的守護進程。
- 它是編寫需要長期運行、無交互的后臺任務程序時常用的函數。