【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);
}
这是看不到子进程变为孤儿进程的过程的!!!
/**
* 功能:我们创建一个孤儿进程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);
}
这是看不到子进程变为孤儿进程的过程的!!!
相关文章推荐
- Linux C函数参考手册(PDF版)
- C#实现进程管理的启动和停止实例
- DOS中判断进程是否存在的方法
- Lua教程(十七):C API简介
- C#进程监控方法实例分析
- 批处理 结束麦咖啡进程的代码
- PowerShell查看进程的所属用户
- C#实现强制关闭当前程序进程
- C#实现读取被进程占用的文件实现方法
- C#获取进程或线程相关信息的方法
- C#实现打造气泡屏幕保护效果
- 使用C#代码获取存储过程返回值
- 简要对比C语言中三个用于退出进程的函数
- C/C++数据对齐详细解析
- 利用C语言来求最大连续子序列乘积的方法
- 字符串的组合算法问题的C语言实现攻略
- VC实现获取当前正在运行的进程
- C 语言基础教程(我的C之旅开始了)[三]
- C++中的extern “C”用法详解