您的位置:首页 > 产品设计 > UI/UE

【APUE】6、孤儿进程组

2015-12-19 18:03 423 查看
关于孤儿进程组,我认为就是当前会话中的所有进程的父进程都不在当前会话中,那么这个会话中的进程就是孤儿进程组

/**
* 功能:我们创建一个孤儿进程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);
}


这是看不到子进程变为孤儿进程的过程的!!!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息