歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux基礎 >> Linux教程 >> linux下的trap命令和SIGHUP信號量詳解(3)

linux下的trap命令和SIGHUP信號量詳解(3)

日期:2017/2/25 10:38:40   编辑:Linux教程
 19) SIGSTOP 停止(stopped)進程的執行. 注意它和terminate以及interrupt的區別: 該進程還未結束, 只是暫停執行. 本信號不能被阻塞, 處理或忽略.

  20) SIGTSTP 停止進程的運行, 但該信號可以被處理和忽略. 用戶鍵入SUSP字符時(通常是Ctrl-Z)發出這個信號

  21) SIGTTIN 當後台作業要從用戶終端讀數據時, 該作業中的所有進程會收到SIGTTIN信號. 缺省時這些進程會停止執行.

  22) SIGTTOU 類似於SIGTTIN, 但在寫終端(或修改終端模式)時收到.

  23) SIGURG 有緊急數據或out-of-band數據到達socket時產生.

  24) SIGXCPU 超過CPU時間資源限制. 這個限制可以由getrlimit/setrlimit來讀取/改變

  25) SIGXFSZ 超過文件大小資源限制.

  26) SIGVTALRM 虛擬時鐘信號. 類似於SIGALRM, 但是計算的是該進程占用的CPU時間.

  27) SIGPROF 類似於SIGALRM/SIGVTALRM, 但包括該進程用的CPU時間以及系統調用的時間.

  28) SIGWINCH 窗口大小改變時發出.

  29) SIGIO 文件描述符准備就緒, 可以開始進行輸入/輸出操作.

  30) SIGPWR Power failure

  對於2和3信號量好理解,屏蔽ctrl+c和ctrl+\。但是1信號量到底什麼作用呢?

  轉自http://blog.csdn.net/cugxueyu/archive/2008/01/16/2046565.aspx

  SIGHUP信號與控制終端

  UNIX中進程組織結構為 session (會話)包含一個前台進程組及一個或多個後台進程組,一個進程組包含多個進程。一個session可能會有一個session首進程,而一個session首進程可能會有一個控制終端。一個進程組可能會有一個進程組首進程。進程組首進程的進程ID與該進程組ID相等。這兒是可能會有,在一定情況之下是沒有的。與終端交互的進程是前台進程,否則便是後台進程。

  SIGHUP會在以下3種情況下被發送給相應的進程:

  1、終端關閉時,該信號被發送到session首進程以及作為job提交的進程(即用 & 符號提交的進程)

  2、session首進程退出時,該信號被發送到該session中的前台進程組中的每一個進程

  3、若父進程退出導致進程組成為孤兒進程組,且該進程組中有進程處於停止狀態(收到SIGSTOP或SIGTSTP信號),該信號會被發送到該進程組中的每一個進程。

  系統對SIGHUP信號的默認處理是終止收到該信號的進程。所以若程序中沒有捕捉該信號,當收到該信號時,進程就會退出。

  下面觀察幾種因終端關閉導致進程退出的情況,在這兒進程退出是因為收到了SIGHUP信號。login shell是session首進程。

  首先寫一個測試程序,代碼如下:

  #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;

  }

  程序中捕捉SIGHUP信號後打印一條信息,pause()使程序暫停。

  編譯後的執行文件為sigtest。

  1、命 令:sigtest front > tt.txt

  操 作:關閉終端

  結 果:tt.txt文件的內容為front : sighup received

  原 因: sigtest是前台進程,終端關閉後,根據上面提到的第1種情況,login shell作為session首進程,會收到SIGHUP信號然後退出。根據第2種情況,sigtest作為前台進程,會收到login shell發出的SIGHUP信號。

  2、命 令:sigtest back > tt.txt &

  操 作:關閉終端

  結 果:tt.txt文件的內容為 back : sighup received

  原 因: sigtest是提交的job,根據上面提到的第1種情況,sigtest會收到SIGHUP信號。

  3、命 令:寫一個shell,內容為[sigtest &],然後執行該shell

  操 作:關閉終端

  結 果:ps -ef | grep sigtest 會看到該進程還在,tt文件為空

  原 因: 執行該shell時,sigtest作為job提交,然後該shell退出,致使sigtest變成了孤兒進程,不再是當前session的job了,因此sigtest即不是session首進程也不是job,不會收到SIGHUP。同時孤兒進程屬於後台進程,因此login shell退出後不會發送SIGHUP給sigtest,因為它只將該信號發送給前台進程。第3條說過若進程組變成孤兒進程組的時候,若有進程處於停止狀態,也會收到SIGHUP信號,但sigtest沒有處於停止狀態,所以不會收到SIGHUP信號。

  4、命 令:nohup sigtest > tt

  操 作:關閉終端

  結 果:tt文件為空

  原 因: nohup可以防止進程收到SIGHUP信號

  至此,我們就清楚了何種情況下終端關閉後進程會退出,何種情況下不會退出。

  要想終端關閉後進程不退出有以下幾種方法,均為通過shell的方式:

  1、編寫shell,內容如下

  trap "" SIGHUP #該句的作用是屏蔽SIGHUP信號,trap可以屏蔽很多信號

  sigtest

  2、nohup sigtest 可以直接在命令行執行,

  若想做完該操作後繼續別的操作,可以 nohup sigtest &

  3、編寫shell,內容如下

  sigtest &

  其實任何將進程變為孤兒進程的方式都可以,包括fork後父進程馬上退出。

Copyright © Linux教程網 All Rights Reserved