作業系統中訊號的基本操作
阿新 • • 發佈:2019-01-09
一、基本概念
1、中斷 中止(暫停)當前正在執行的任務,轉而執行其他任務,這種行為叫中斷。 硬體中斷:來自硬體的中斷。 軟體中斷:來子軟體的中斷。 2、訊號是一種軟體中斷 它為程序非同步執行任務提供了一種機制。 1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL 5) SIGTRAP 6) SIGABRT 7) SIGBUS 8) SIGFPE 9) SIGKILL 10) SIGUSR1 11) SIGSEGV 12) SIGUSR2 13) SIGPIPE 14) SIGALRM 15) SIGTERM 16) SIGSTKFLT 17) SIGCHLD 18) SIGCONT 19) SIGSTOP 20) SIGTSTP 21) SIGTTIN 22) SIGTTOU 23) SIGURG 24) SIGXCPU 25) SIGXFSZ 26) SIGVTALRM 27) SIGPROF 28) SIGWINCH 29) SIGIO 30) SIGPWR 31) SIGSYS 34) SIGRTMIN 35) SIGRTMIN+1 36) SIGRTMIN+2 37) SIGRTMIN+3 38) SIGRTMIN+4 39) SIGRTMIN+5 40) SIGRTMIN+6 41) SIGRTMIN+7 42) SIGRTMIN+8 43) SIGRTMIN+9 44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12 47) SIGRTMIN+13 48) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14 51) SIGRTMAX-13 52) SIGRTMAX-12 53) SIGRTMAX-11 54) SIGRTMAX-10 55) SIGRTMAX-9 56) SIGRTMAX-8 57) SIGRTMAX-7 58) SIGRTMAX-6 59) SIGRTMAX-5 60) SIGRTMAX-4 61) SIGRTMAX-3 62) SIGRTMAX-2 63) SIGRTMAX-1 64) SIGRTMAX 3、常見的訊號 SIGINT 終端中斷符訊號 Ctrl+c 發出 SIGQUIT 終端退出符型號 Ctrl+ \ 發出 SIGFPE 算術異常訊號 程式執行的除0操作 SIGSEGV 段錯誤停下 非法使用了記憶體 SIGSTOP 暫停訊號 不能被捕獲或忽略,收到SIGCONT訊號才能繼續 SIGCONT 繼續訊號 不能被捕獲或忽略,可以讓停止的程序執行。 4、不可靠訊號 kill -l可以顯示出所有可用的訊號。 1到31 是建立在早期的機制上的,不支援排隊,同一個訊號產生多次,只處理一次(單位時間內處理一次),這種機制可能會導致訊號丟失。 5、可靠訊號(兩種訊號相互獨立,互不干擾) 34到64 是建立在新機制的訊號,支援排隊,不會丟失。 6、訊號的處理 1、忽略 2、終止 3、終止+core(記錄著記憶體的使用情況)(~/.bashrc可以記錄在環境中) 第一步,執行:ulimit -c unlimited ,使用系統弄夠生成core檔案。 第二部:gcc -g code.c 加入除錯資訊 第三步:重新執行程式,生成帶除錯資訊的core檔案 第四步:使用gdb a.out core 檔案進行除錯。 第五步: where 顯示在什麼位置什麼原因產生的錯誤。 4、捕獲並處理,當訊號發生時,作業系統會呼叫一個預先註冊好的一個處理函式。
二、訊號的捕獲
#include <signal.h> typedef void (*sighandler_t)(int);//訊號處理函式的格式 sighandler_t signal(int signum, sighandler_t handler); 功能:向核心註冊一個訊號處理函式 signum:要捕獲並處理的型號 han-dler:當訊號發生時要執行的函式 注意:這個步驟一般寫在程式的開始部分,或者專案初始化階段。 程式碼產生(除0、非法使用記憶體)的訊號,這種訊號也能被捕獲,但是當訊號處理完後, 又會回到產生錯誤的位置,如果這個錯誤沒有消除又會繼續產生訊號,會形成死迴圈,解決方法: 1、在訊號處理函式中把錯誤消除掉 2、把資料儲存,然後安全退出。exit(1)函式,無論在哪都可以直接退出。
三、傳送訊號
1、鍵盤傳送訊號 Ctrl+c SIGINT Ctrl+\ SIGQUIT Ctrl+z SIGSTOP 2、錯誤產生訊號 除0操作 SIGFPE 非法訪問記憶體 SIGSEGV 硬體故障 SIGBUS (記憶體燒了,U盤退出) 3、命令傳送訊號 #include <sys/types.h> #include <unistd.h> pid_t getpid(void); pid_t getppid(void); 功能:獲取程序號; 返回值:當前程序的程序號 kill -sig(訊號編號) 程序號。 ps -aux (可以看程序號)。 kill all 程式名 向所有叫這個名字的程序傳送訊號。 4、函式傳送訊號 #include <sys/types.h> #include <signal.h> int kill(pid_t pid, int sig); 功能:向指定的程序傳送訊號 pid: pid > 0 向指定的程序傳送訊號 pid = 0 向同組的程序傳送訊號 pid = -1 向所有程序傳送訊號(以許可權作為範圍)。 (root 使用者可以向所有的程序傳送訊號,普通使用者只能對自己的程序傳送訊號) pid < -1 向程序號等於pid絕對值的程序傳送訊號。 sig:訊號的編號 如果sig的值不存在,不會發送,但也不會返回錯誤。 當傳送的程序不存在時,才會返回錯誤,這個功能可以用來檢查一個程序是否存在。 返回值:一般0表示成功,負數表示失敗。 #include <signal.h> int raise(int sig); 功能:向當前程序傳送訊號。(向自己傳送訊號) 返回值:成功返回 0 ,失敗返回-1(核心出問題)(如果訊號不存在也能傳送,也算成功,返回值為0);