• 二十八、Linux 进程与信号---前台进程组


    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

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

    28.2 例子

      

     1 #include <stdio.h>
     2 #include <stdlib.h>
     3 #include <unistd.h>
     4 #include <sys/wait.h>
     5 
     6 int main(void)
     7 {
     8     pid_t group1,group2;
     9 
    10     //创建进程组1,父进程作为组长进程
    11     setpgid(getpid(), getpid());
    12     group1 = getpgid(getpid());
    13 
    14     pid_t pid;
    15     int i = 0;
    16     for(; i < 3; i++) {
    17         pid = fork();
    18         if(pid < 0) {
    19             perror("fork error");
    20             exit(1);
    21         } else if(pid > 0) {
    22             if(i == 0) {
    23                 setpgid(pid, pid);
    24                 group2 = getpgid(pid);
    25             }
    26 
    27             if(i == 1) {
    28                 setpgid(pid, group2);
    29             }
    30 
    31             if(i == 2) {
    32                 setpgid(pid, group1);
    33             }
    34         } else {
    35             
    36             if(i == 0) {
    37                 setpgid(getpid(), getpid());
    38                 group2 = getpgid(getpid());
    39             }
    40 
    41             if(i == 1) {
    42                 setpgid(getpid(), group2);
    43             }
    44 
    45             if(i == 2) {
    46                 setpgid(getpid(), group1);
    47             }
    48 
    49             break;
    50         }
    51     }
    52 
    53     printf("pid: %d, ppid: %d, pgid: %d
    ", getpid(), getppid(), getpgid(0));
    54     pause();
    55 
    56     exit(0);
    57 }

      编译执行

      

      查询下进程:

      

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

      然后再查看进程:

      

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

      进行设置 group2 为前台进程组

     1 #include <stdio.h>
     2 #include <stdlib.h>
     3 #include <unistd.h>
     4 #include <sys/wait.h>
     5 
     6 int main(void)
     7 {
     8     pid_t group1,group2;
     9 
    10     //创建进程组1,父进程作为组长进程
    11     setpgid(getpid(), getpid());
    12     group1 = getpgid(getpid());
    13 
    14     pid_t pid;
    15     int i = 0;
    16     for(; i < 3; i++) {
    17         pid = fork();
    18         if(pid < 0) {
    19             perror("fork error");
    20             exit(1);
    21         } else if(pid > 0) {
    22             if(i == 0) {
    23                 setpgid(pid, pid);
    24                 group2 = getpgid(pid);
    25             }
    26 
    27             if(i == 1) {
    28                 setpgid(pid, group2);
    29 
    30                 //将 group2 设置为前台进程组
    31                 tcsetpgrp(0, group2);
    32             }
    33 
    34             if(i == 2) {
    35                 setpgid(pid, group1);
    36             }
    37         } else {
    38             
    39             if(i == 0) {
    40                 setpgid(getpid(), getpid());
    41                 group2 = getpgid(getpid());
    42             }
    43 
    44             if(i == 1) {
    45                 setpgid(getpid(), group2);
    46 
    47                 tcsetpgrp(0, group2);
    48             }
    49 
    50             if(i == 2) {
    51                 setpgid(getpid(), group1);
    52             }
    53 
    54             break;
    55         }
    56     }
    57 
    58     printf("pid: %d, ppid: %d, pgid: %d
    ", getpid(), getppid(), getpgid(0));
    59     pause();
    60 
    61     exit(0);
    62 }
  • 相关阅读:
    pyqt的setObjectName()/findChild()
    pyqt的多Button的点击事件的槽函数的区分发送signal的按钮。
    分布式存储
    QTableWidget的表头颜色设置
    QListView的子项的ViewMode
    QHeaderView的点击和双击事件
    LeetCode(63):不同路径 II
    LeetCode(62):不同路径
    LeetCode(61):旋转链表
    LeetCode(60): 第k个排列
  • 原文地址:https://www.cnblogs.com/kele-dad/p/9169444.html
Copyright © 2020-2023  润新知