【APUE】6、孤儿进程组

关于孤儿进程组,我认为就是当前会话中的所有进程的父进程都不在当前会话中,那么这个会话中的进程就是孤儿进程组


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

这是看不到子进程变为孤儿进程的过程的!!!













评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值