28.1 介绍

28.1.1 概念

  • 自动接受终端信号的组称为前台进程组
  • 在终端通过 ctrl + c 等动作产生的信号首先被前台进程组接受
  • 在 shell 启动的若干个进程组默认是父进程所在的组为前台进程组
  • 除非是默认,否则都要通过调度才能成为前台进程组

28.1.1 函数 tcgetpgrp 和 tcsetpgrp

(1)tcgetpgrp 函数---获得前台进程组ID

#include <unistd.h>
int tcgetpgrp(int fd);
  • 函数功能:获得前台进程组 ID
  • 返回值:若成功返回前台进程组ID,出错返回 -1

(2)tcsetpgrp 函数---设置前台进程组ID

 #include <unistd.h>
int tcsetpgrp(int fd, pid_t pgrpid);
  • 函数功能:使用 pgrpid 设置前台进程组ID,fd 必须引用该会话的控制终端,0 代表当前正在使用的终端
  • 返回值:成功返回 0,出错返回 -1

28.2 例子

  

 #include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h> int main(void)
{
pid_t group1,group2; //创建进程组1,父进程作为组长进程
setpgid(getpid(), getpid());
group1 = getpgid(getpid()); pid_t pid;
int i = ;
for(; i < ; i++) {
pid = fork();
if(pid < ) {
perror("fork error");
exit();
} else if(pid > ) {
if(i == ) {
setpgid(pid, pid);
group2 = getpgid(pid);
} if(i == ) {
setpgid(pid, group2);
} if(i == ) {
setpgid(pid, group1);
}
} else { if(i == ) {
setpgid(getpid(), getpid());
group2 = getpgid(getpid());
} if(i == ) {
setpgid(getpid(), group2);
} if(i == ) {
setpgid(getpid(), group1);
} break;
}
} printf("pid: %d, ppid: %d, pgid: %d\n", getpid(), getppid(), getpgid());
pause(); exit();
}

  编译执行

  

  查询下进程:

  

  按下 ctrl-c 停止运行的进程

  然后再查看进程:

  

  8956 和 8959 为默认进程组 group1,执行完 ctrl +c 后关闭,但是 group2 没有关闭,可以发现进程组默认是父进程那一组

  进行设置 group2 为前台进程组

 #include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h> int main(void)
{
pid_t group1,group2; //创建进程组1,父进程作为组长进程
setpgid(getpid(), getpid());
group1 = getpgid(getpid()); pid_t pid;
int i = ;
for(; i < ; i++) {
pid = fork();
if(pid < ) {
perror("fork error");
exit();
} else if(pid > ) {
if(i == ) {
setpgid(pid, pid);
group2 = getpgid(pid);
} if(i == ) {
setpgid(pid, group2); //将 group2 设置为前台进程组
tcsetpgrp(, group2);
} if(i == ) {
setpgid(pid, group1);
}
} else { if(i == ) {
setpgid(getpid(), getpid());
group2 = getpgid(getpid());
} if(i == ) {
setpgid(getpid(), group2); tcsetpgrp(, group2);
} if(i == ) {
setpgid(getpid(), group1);
} break;
}
} printf("pid: %d, ppid: %d, pgid: %d\n", getpid(), getppid(), getpgid());
pause(); exit();
}

二十八、Linux 进程与信号---前台进程组的更多相关文章

  1. 二十、Linux 进程与信号---非局部跳转

    20.1 setjmp 和 longjmp 函数 20.1.1 函数介绍 #include <setjmp.h> int setjmp(jmp_buf env); 函数功能:设置非局部跳转 ...

  2. 三十、Linux 进程与信号——信号的概念及 signal 函数

    30.1 信号的基本概念 信号(signal)机制是Linux 系统中最为古老的进程之间的通信机制,解决进程在正常运行过程中被中断的问题,导致进程的处理流程会发生变化 信号是软件中断 信号是异步事件 ...

  3. 二十三、Linux 进程与信号---进程链和进程扇、守护进程和孤儿进程以及僵尸进程

    23.1 进程链和进程扇 23.1.1 概念 进程链:一个父进程构建出一个子进程,子进程再构建出子子进程,子子进程构建出子子子进程.... 这种就为进程链 进程扇:一个父进程构建出多个子进程,子进程都 ...

  4. 二十七、Linux 进程与信号---进程组和组长进程

    27.1 进程组 27.1.1 进程组介绍 进程组为一个或多个进程的集合 进程组可以接受同一终端的各种信号,同一个信号发送进程组等于发送给组中的所有进程 每个进程组有唯一的进程组 ID 进程组的消亡要 ...

  5. 二十一、Linux 进程与信号---进程查看和进程状态、进程调度和进程状态变化、进程标识

    21.1 进程查看和进程状态 21.1.1 ps 指令 ps 指令通常可以查看到进程的 ID.进程的用户 ID.进程状态和进程的 Command ps:查看当前用户启动的进程 ps -ef:详细查看后 ...

  6. 二十一、Linux 进程与信号---进程资源限制

    21.1 进程资源限制 在操作系统中,我们能够通过函数getrlimit().setrlimit()分别获得.设置每个进程能够创建的各种系统资源的限制使用量. 21.1.1 函数 #include & ...

  7. [转帖]十二 个经典 Linux 进程管理命令介绍

    https://www.cnblogs.com/swordxia/p/4550825.html 接了 http referer 头 没法显示图片 可以去原始blog 里面去查看.   随笔- 109  ...

  8. Bootstrap <基础二十八>列表组

    列表组.列表组件用于以列表形式呈现复杂的和自定义的内容.创建一个基本的列表组的步骤如下: 向元素 <ul> 添加 class .list-group. 向 <li> 添加 cl ...

  9. Web 前端开发人员和设计师必读文章推荐【系列二十八】

    <Web 前端开发精华文章推荐>2014年第7期(总第28期)和大家见面了.梦想天空博客关注 前端开发 技术,分享各类能够提升网站用户体验的优秀 jQuery 插件,展示前沿的 HTML5 ...

随机推荐

  1. 前端基础-- HTML

    HTML知识 HTML介绍 Web服务本质 浏览器发请求 --> HTTP协议 --> 服务端接收请求 --> 服务端返回响应 --> 服务端把HTML文件内容发给浏览器 -- ...

  2. OO第三阶段纪实

    $0 写在前面 万里长征已过大半,即将迎来胜利的曙光.一路走来,经历过种种艰难,体会颇深.希望能记录下这篇博文,来总结这一个月来的收获与感悟. $1 规格化设计的发展历史 上世纪50年代,软件伴随着第 ...

  3. rxjs学习笔记

    api List Rx.Observable.amb(...args) -存在竞争关系,amb里的流只能触发一个,并且忽略其他未处理的流. eq: <body> <input id= ...

  4. JavaScript深入之从原型到原型链

    构造函数创建对象 我们先使用构造函数创建一个对象: function Person(){} var person = new Person(); person.name = 'Kevin'; cons ...

  5. Django session相关操作

    Django session 是存储在数据库中的所以要先跟数据库建立连接 本连接有Django跟数据库建立连接的操作:https://www.cnblogs.com/Niuxingyu/p/10296 ...

  6. Flask flask_script扩展库

    flask_script 1.安装:进入到虚拟环境中,pip install flask_script 2.flask_script 作用:可以通过命令行的形式来操作Flask,例如通过命令跑一个开发 ...

  7. Unity 网络编程(Socket)应用

    服务器端的整体思路: 1.初始化IP地址和端口号以及套接字等字段: 2.绑定IP启动服务器,开始监听消息  socketServer.Listen(10): 3.开启一个后台线程接受客户端的连接 so ...

  8. C++ MFC------ 快捷键

    创建快捷键 该文讲解如何给dialog的菜单或者按钮添加快捷键. 1.局部快捷键 点击控件,右键点“属性”,在属性Caption后添加&Key,例如: &Y,即通过按Alt+Y即可触发 ...

  9. Linux系统CPU相关信息查询

    Linux系统CPU相关信息查询 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.lscpu常用参数介绍 1>.查看帮助信息 [root@node105 ~]# lscpu ...

  10. Kafka技术内幕 读书笔记之(五) 协调者——延迟的加入组操作

      协调者处理不同消费者的“加入组请求”,由于不能立即返回“加入组响应”给每个消费者,它会创建一个“延迟操作”,表示协调者会延迟发送“加入组响应”给消费者 . 但协调者不会为每个消费者的 “加入组请求 ...