SIGHUP信號與控制終端
#include <stdio.h>
#include
<signal.h>
char **
args;
void exithandle(int
sig)
{
printf("%s : sighup received ",args[1]);
}
int main(int argc,char **argv)
{
args = argv;
signal(SIGHUP,exithandle);
pause();
return 0;
}
signal信號函數,第一個參數表示需要處理的信號值(SIGHUP),第二個參數為處理函數或者是一個表示,這里,SIG_IGN表示忽略SIGHUP那個注冊的信號。
SIGHUP
和控制台操作有關,當控制台被關閉時系統會向擁有控制台sessionID的所有進程發送HUP信號,默認HUP信號的action是
exit,如果遠程登陸啟動某個服務進程並在程序運行時關閉連接的話會導致服務進程退出,所以一般服務進程都會用nohup工具啟動或寫成一個 daemon。
、sighup與nohup
sighup(掛斷)信號:
在控制終端或者控制進程死亡時向關聯會話中的進程發出,默認進程對SIGHUP信號的處理是終止程序,所以我們在shell下建立的程序,在登錄退出連接斷開之后,會一並退出。
網上搜索到的解釋: 什么時候會發送 SIGHUP信號?當一個進程組成為孤兒進程組時,posix.1要求向孤兒進程組中處於停止狀態的進程發送SIGHUP(掛斷)信號,系統對於這種信號的默認處理是終止進程,然而如果無視這個信號或者另行處理的話,那么這個掛起進程仍可以繼續執行。
nohup命令:
故名思議就是忽略SIGHUP信號,一般搭配 & 一起使用,& 表示將此程序提交為后台作業或者說后台進程組。執行下面的命令
nohup bash -c "tail -f /var/log/messages | grep sys" &
1
nohup與&啟動的程序, 在終端還未關閉時,完全不像傳統的守護進程,因為其不是會話首進程且持有終端,只是其忽略了SIGHUP信號
從nohup源碼就可以看到,其實nohup只做了3件事情
dofile函數將輸出重定向到nohup.out文件
signal函數設置SIGHUP信號處理函數為SIG_IGN宏(指向sigignore函數),以此忽略SIG_HUP信號
execvp函數用新的程序替換當前進程的代碼段、數據段、堆段和棧段。
execvp 函數執行后,新程序(並沒有fork進程)會繼承一些調用進程屬性,比如:進程id、會話id,控制終端等
登錄連接斷開之后
在終端關閉后,nohup起到類似守護進程的效果,但是跟傳統的守護進程還是有區別的
nohup創建的進程工作目錄是你執行命令時所在的目錄
0 1 2 標准輸入 標准輸出 標准錯誤 指向nohup.out文件
nohup創建的進程組中,除首長進程的父進程id變為1之外,其余進程依然保留原來的會話id、進程組id、父進程id,都保持不變
網上搜索到的解釋: nohup命令可以將程序以忽略掛起信號的方式運行起來,被運行的程序的輸出信息將不會顯示到終端。
無論是否將 nohup 命令的輸出重定向到終端,輸出都將附加到當前目錄的 nohup.out 文件中。如果當前目錄的 nohup.out
文件不可寫,輸出重定向到$HOME/nohup.out文件中。如果沒有文件能創建或打開以用於追加,那么 command
參數指定的命令不可調用。如果標准錯誤是一個終端,那么把指定的命令寫給標准錯誤的所有輸出作為標准輸出重定向到相同的文件描述符。
linux——signal信號(SIGHUP、SIGINT、SIGQUIT、SIGILL、SIGTRAP、SIGABRT...........................)
https://blog.csdn.net/u014470361/article/details/83591513
