#include "myapue.h" #include <errno.h> static void sig_hup(int signo) { printf("SIGHUP received, pid = %ld\n", (long)getpid()); } static void pr_ids(char *name) { printf("%s: pid = %ld, ppid = %ld, pgrp = %ld, tpgrp = %ld\n",\ name, (long)getpid(), (long)getppid(), (long)getpgrp(),\ (long)tcgetpgrp(STDIN_FILENO)); fflush(stdout); } int main(void) { char c; pid_t pid; pr_ids("parent"); if((pid = fork()) < 0) err_sys("fork error"); else if(pid > 0){ sleep(5); } else{ pr_ids("child"); signal(SIGHUP, sig_hup); kill(getpid(), SIGTSTP);//向子進程本身發出掛起信號,stop ourself pr_ids("child"); if(read(STDIN_FILENO, &c, 1) != 1) printf("read error %d on controlling TTY\n", errno); } exit(0); }
<245>9.10孤兒進程組shell
(1)函數
getpid():返回調用進程的進程ID。spa
getppid():返回調用進程的父進程ID。code
getpgrp():返回調用進程的進程組ID。(同一進程組中的各個進程接收來自同一終端的各類信號)接口
tcgetpgrp(int fd):若成功,返回前臺進程組ID。它與在fd上打開的終端相關聯。進程
前臺進程組:終端設備驅動程序將終端輸入和終端產生的信號發送到此處。get
fflush(FILE *fp):強制沖洗一個流,使該流全部未寫的數據都被傳送至內核。it
<118>若fp爲NULL,則全部輸出流被沖洗。io
stdout:標準I/O常量,定義在頭文件<stdio.h>中。class
STDIN_FILENO:標準輸入的文件描述符。
(2)
signal函數<256>:此函數是UNIX信號機制最簡單的接口。用於創建信號處理程序。
typedef void (*sighandler_t)(int);
sighandler_t signal(int signum, sighandler_t handler);
signum參數是信號名
SIGHUP:(掛斷信號)終端接口檢測到一個鏈接斷開,則將此信號送給與該終端相關的控制進程(會話首進程)。
(此處,在父進程終止後,進程組包含一箇中止的進程,進程組成爲孤兒進程組,POSIX.1要求向新孤兒進程組中處於中止狀態的每個進程發送掛斷信號)
handler:當接到此信號後要調用的函數的地址。或爲常量SIG_IGN,SIG_DFL。
(3)<267>
kill函數:將信號發送給進程或進程組。
SIGTSTP:(此處將中止子進程)交互中止信號,當用戶在終端上按掛起鍵時,終端驅動程序產生此信號。該信號發送至前臺進程組中的全部進程。
(4)
孤兒進程:父進程已終止的進程,由init進程(進程ID爲1)「收養」。
孤兒進程組:<245>
(5)
父進程終止時,子進程變成後臺進程組,由於父進程由shell做爲前臺做業執行。當後臺進程組試圖讀控制終端時,對該後臺進程組產生SIGTTIN。