进程组

1. 进程组

  • 概念 

进程组是一个或多个进程的集合。

  • kill发送给进程组

使用 kill -n -pgid 可以将信号 n 发送到进程组 pgid 中的所有进程。例如命令 kill -9 -4115 表示杀死进程组 4115 中的所有进程。

2. 进程组的创建与设置

pid_t getpgrp(void);
返回:调用进程的进程组ID.

返回:调用进程的进程组ID.

   pid_t getpgid(pid_t pid);

返回:进程pid所在进程组的ID,出错返回-1;

setpgid(pid, pid)

进程调用setpid可以加入一个现有的进程组或者创建一个新进程组。

3. 程序清单

题目:利用进程扇完成一个小实验。该进程扇有 1 个父进程和 3 个子进程,我们希望达到图 1 中的效果,即将进程 0 (父进程)和进程 1 设置成一组,假设为组 1,将进程 2 和 进程 3 设置成另一个组,假设为组 2. 另外,我们希望进程 0 和进程 2 分别是这两个组的组长。

                                                                           

3.1 错误代码:

#include <unistd.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>


int main() {
  int pid, i;
  int group1, group2;

  // 设置父进程(进程 0)为组长 
  setpgid(getpid(), getpid());
  group1 = getpgid(getpid());

  for (i = 1; i <= 3; ++i) {
    pid = fork();
    if (pid == 0) {
      // child
      if (i == 1) {
        // 如果 group1 根本不存在,就会出问题。
        // 比如进程 0 已经运行结束。
        setpgid(getpid(), group1);
      }   
      else if (i == 2) {
        setpgid(getpid(), getpid());
        group2 = getpgid(getpid());
      }   
      else if (i == 3) {
        // 试想如果进程 2 还没运行,进程 3 先运行了,
        // 这时候 group2 还未进行设置,这里就会有问题。
        // 或者进程 2 已经结束,那进程 3 的设置也会失败
        setpgid(getpid(), group2);
      }   
      break;
    }   
    else if (pid < 0) {
      perror("fork");
      return -1; 
    }   
  }

  printf("%d, pid: %d -> ppid: %d, pgid: [%d]\n", i%4, getpid(), getppid(), getpgid(getpid()));

  while(1)
    sleep(3);
  return 0;
}

输出结果:

扫描二维码关注公众号,回复: 3680632 查看本文章

3.2 正确代码:

#include <unistd.h>
#include <fcntl.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
// 创建一个进程扇,并实现如图所示的进程组分配
 
int main(void) {
    setpgid(getpid(), getpid());
    pid_t group1 = getpgid(getpid());
    pid_t group2;
 
    int i = 0;
    for(; i < 3; ++i) {
        pid_t pid = fork();

        if(pid < 0) {
            perror("fork error");
            exit(1);
        }
        else if(pid > 0) {
            // parent process
            if(i == 0)
                setpgid(pid, group1);
            if(i == 1) {
                setpgid(pid, pid);
                group2 = getpgid(pid);
            }
            if(i == 2)
                setpgid(pid, group2);
        }
        else {
            // child process
            if(i == 0)
                setpgid(getpid(), group1);
            if(i == 1) {
                setpgid(getpid(), getpid());
                group2 = getpgid(getpid());
            }
            if(i == 2)
                setpgid(getpid(), group2);
            break;
        }
    }
    printf("pid:%d, ppid:%d, pgid:%d\n", getpid(), getppid(), getpgid(getpid()));
 
    for(int i = 0; i < 3; ++i)
        wait(0);
 
    return 0;
}

输出结果:

题目:利用进程链完成一个小实验,希望达到图 1 中的效果,即将进程 0 (父进程)和进程 2 设置成一组,假设为组 1,将进程 1 和 进程 3 设置成另一个组,假设为组 2. 另外,我们希望进程 0 和进程 1 分别是这两个组的组长。

             

                                                                      

3.3 测试代码

#include <unistd.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>

int main() {
  int pid, i;
  int group1, group2;

  setpgid(getpid(), getpid());
  group1 = getpgid(getpid());


  for (i = 0; i < 3; ++i) {
    pid = fork();
    if (pid > 0) {
      // father
      if (i == 0) {
        setpgid(pid, pid);
        group2 = getpgid(pid);
      }   
      else if (i == 1) {
        setpgid(pid, group1);
      }   
      else if (i == 2) {
        setpgid(pid, group2);
      }   
      break;
    }   
    else if (pid == 0) {
      // child
      if (i == 0) {
        setpgid(getpid(), getpid());
        group2 = getpgid(getpid());
      }   
      else if (i == 1) {
        setpgid(getpid(), group1);
      }   
      else if (i == 2) {
        setpgid(getpid(), group2);
      }   
    }   
    else if (pid < 0) {
      perror("fork");
      return -1; 
    }   
  }

  printf("进程 %d, pid: %d -> ppid: %d, pgid: [%d]\n", i, getpid(), getppid(), getpgid(getpid()));
  while(1) sleep(1);
  return 0;
}

输出结果:

4. 参考资料

猜你喜欢

转载自blog.csdn.net/isunbin/article/details/83041897