關于孤兒程序組,我認為就是目前會話中的所有程序的父程序都不在目前會話中,那麼這個會話中的程序就是孤兒程序組
/**
* 功能:我們建立一個孤兒程序or程序組
* 時間:2015年12月19日17:01:48
* 作者:cutter_point
*/
#include "../util/apue.h"
#include "../util/error.c"
#include <errno.h>
//用來處理挂斷信号的函數
static void sig_hup(int signo)
{
printf("收到挂斷信号,pid=%ld\n", (long)getpid());
}
//輸出相應的id号
static void pr_ids(char *name)
{
printf("%s: 目前程序id = %ld, 父程序id = %ld, 目前程序組 = %ld, 前台程序組 = %ld\n",
name, (long)getpid(), (long)getppid(), (long)getpgrp(),
(long)tcgetpgrp(STDIN_FILENO));
//清空緩存
fflush(stdout);
}
int main(int argc, char *argv[])
{
char c;
pid_t pid; //存放程序id
//輸出父程序的一些id值
pr_ids("父程序");
if((pid = fork()) < 0)
err_sys("fork失敗");
else if(pid > 0)
sleep(5); //為了子程序在父程序結束之前還可以執行一段
else
{
pr_ids("子程序");
//建立信号機制,signal第二個參數 typedef void (*sighandler_t)(int);這個是一個int參數的函數指針
signal(SIGHUP, sig_hup); //這個是挂斷信号
/*
SIGSTOP:停止(stopped)程序的執行.
注意它和terminate以及interrupt的差別:該程序還未結束, 隻是暫停執行.
本信号不能被阻塞, 處理或忽略.
SIGTSTP:停止程序的運作, 但該信号可以被處理和忽略. 使用者鍵入SUSP字元時(通常是Ctrl-Z)發出這個信号
*/
kill(getpid(), SIGTSTP); //用于向任何程序組或程序發送信号。
pr_ids("子程序");
if(read(STDIN_FILENO, &c, 1) != 1)
printf("讀取錯誤代碼: %d on controlling TTY\n", errno);
}//else
exit(0);
}
執行的結果:
首先我們得到父程序的一系列id号,然後我們把父程序sleep,執行子程序檢視子程序的一系列id号,我們發現沒什麼問題,那麼目前的程序都是ok的
好的,接下來我們建立信号機制,當我們父程序挂斷的時候,用來提示
然後調用kill函數暫停我們的子程序,注意暫停,不是關閉,然後父程序結束之後子程序的父程序結束,那麼子程序交給init托管,是以父程序id變為1,前台組也變成了父程序的父程序id組,是以這個時候子程序所在的組變成了一個孤兒程序組!!!
我們還可以吧父程序的sleep修改為sleep(0),執行之後我們會發現,後面子程序都變成第二個結果了,因為子程序還沒執行,父程序就已經結束了,子程序早早成為孤兒程序
/**
* 功能:我們建立一個孤兒程序or程序組,修改
* 時間:2015年12月19日17:26:46
* 作者:cutter_point
*/
#include "../util/apue.h"
#include "../util/error.c"
#include <errno.h>
//用來處理挂斷信号的函數
static void sig_hup(int signo)
{
printf("收到挂斷信号,pid=%ld\n", (long)getpid());
}
//輸出相應的id号
static void pr_ids(char *name)
{
printf("%s: 目前程序id = %ld, 父程序id = %ld, 目前程序組 = %ld, 前台程序組 = %ld\n",
name, (long)getpid(), (long)getppid(), (long)getpgrp(),
(long)tcgetpgrp(STDIN_FILENO)); //一般是0,1,2
//清空緩存
//fflush(stdout);
}
int main(int argc, char *argv[])
{
char c;
pid_t pid; //存放程序id
//輸出父程序的一些id值
pr_ids("父程序");
if((pid = fork()) < 0)
err_sys("fork失敗");
else if(pid > 0)
sleep(0); //為了子程序在父程序結束之前還可以執行一段
else
{
pr_ids("子程序");
//建立信号機制,signal第二個參數 typedef void (*sighandler_t)(int);這個是一個int參數的函數指針
signal(SIGHUP, sig_hup); //這個是挂斷信号,這個要在kill之前,不然程序停止在哪裡就無法使用了
/*
SIGSTOP:停止(stopped)程序的執行.
注意它和terminate以及interrupt的差別:該程序還未結束, 隻是暫停執行.
本信号不能被阻塞, 處理或忽略.
SIGTSTP:停止程序的運作, 但該信号可以被處理和忽略. 使用者鍵入SUSP字元時(通常是Ctrl-Z)發出這個信号
*/
printf("#############################begin\n");
kill(getpid(), SIGTSTP); //用于向任何程序組或程序發送信号。
printf("#############################end\n");
pr_ids("子程序");
if(read(STDIN_FILENO, &c, 1) != 1)
printf("讀取錯誤代碼: %d on controlling TTY\n", errno);
}//else
exit(0);
}
這是看不到子程序變為孤兒程序的過程的!!!