17 Process Groups and Terminal Signaling

这一生的挚爱 提交于 2019-12-22 23:40:04

1 Pipelines and Process Groups

1.1 Pipeline of processes

1.the pipeline executes in parallel
sleep 10 | sleep 20 | sleep 30 | sleep 50 &

1.2 Process Grouping for Jobs

  1. A process group is a way to group processes into distinct jobs that are linked
  2. a session is way to link process groups under a single interruptive unit, like the terminal.

在这里插入图片描述

2 Programming with Process Groups

获得pid/pgid 描述
pid_t getpid() get the process id for the calling process
pid_t getppid() get the process id of the parent of the calling proces
pid_t getpgrp() get the prcesso group id of the calling process
pid_t getpgid(pid_t pid) get the process group id for the proces identified by pid
设置pgid 描述
pid_t setpgrp() set the process group of the calling process to iteself, i.e. after a call to setpgr(), the following condition holds getpid() == getpgrp().
pid_t setpgid(pid_t pid, pid_t pgid) set the process group id of the process identified by pid to the pgid, if pid is 0, then set the process group id of the calling process, and if pgid is 0, then the pid of the process identified by pid and is made the same as its process group, i.e., setpgid(0,0) is equivalent to calling setpgrp().

2.1 Retrieving the Process Group

  1. Each process group has a unique process group identifier, or pgid
  2. Upon a fork(), the child process inherits the parent’s process group.
int main(int argc, char * argv[]){
/*inherit_pgid.c*/

  pid_t c_pid,pgid,pid;

  c_pid = fork();

  if(c_pid == 0){
    /* CHILD */

    pgid = getpgrp();
    pid = getpid();

    printf("Child:  pid: %d pgid: *%d*\n", pid, pgid);

  }else if (c_pid > 0){
    /* PARRENT */

    pgid = getpgrp();
    pid = getpid();

    printf("Parent: pid: %d pgid: *%d*\n", pid, pgid);

  }else{
    /* ERROR */
    perror(argv[0]);
    _exit(1);
  }

  return 0;
}

1.tty shell 并不是其执行进程的父进程,不具有相同的gpid
2.shell will fork each process separately in a job and assign the process group id based on the first child forked
3.这样才能通过ctrl + c等来操作指定的进程组

/*getpgrp.c*/
int main(int argc, char * argv[]){

  pid_t pid, pgid; //process id and process group for this program                                                                         
  pid_t ppid, ppgid; //process id and proces group for the _parent_                                                                        

  //current 
  pid = getpid();
  pgid = getpgrp();

  //parent
  ppid = getppid();
  ppgid = getpgid(ppid);

  //print this parent's process pid and pgid                                                                                               
  printf("%s: (current) pid:%d pgid:%d\n", argv[0], pid, pgid);
  printf("%s: (parrent) ppid:%d pgid:%d\n", argv[0], ppid, ppgid);

  return 0;
}

2.2 Setting the Process Group

方法 描述

setpgrp() : sets the process group of the calling process to itself.
setpgid(pid_t pid, pid_t pgid) : set the process group of the process identified by pid to pgid.

/*setpgrp.c*/
int main(int argc, char * argv[]){

  pid_t cpid, pid, pgid, cpgid; //process id's and process groups

  cpid = fork();

  if( cpid == 0 ){
    /* CHILD */

    //set process group to itself
    setpgrp();

    //print the pid, and pgid of child from child
    pid = getpid();
    pgid = getpgrp();
    printf("Child:          pid:%d pgid:*%d*\n", pid, pgid);

  }else if( cpid > 0 ){
    /* PARRENT */

    //print the pid, and pgid of parent
    pid = getpid();
    pgid = getpgrp();
    printf("Parent:         pid:%d pgid: %d \n", pid, pgid);    

    //print the pid, and pgid of child from parent
    cpgid = getpgid(cpid);
    printf("Parent: Child's pid:%d pgid:*%d*\n", cpid, cpgid);

  }else{
    /*ERROR*/
    perror("fork");
    _exit(1);
  }

  return 0;
}
  1. race condition 无法判断父进程和子进程那个先执行
  2. you should call setpgid()=/=setpgrp() in both the parent and the child before anything depends on those values.
/*setpgid.c*/
int main(int argc, char * argv[]){

  pid_t cpid, pid, pgid, cpgid; //process id's and process groups

  cpid = fork();

  if( cpid == 0 ){
    /* CHILD */

    //set process group to itself
    setpgrp(); //<---------------------------!

    //print the pid, and pgid of child from child
    pid = getpid();
    pgid = getpgrp();
    printf("Child:          pid:%d pgid:*%d*\n", pid, pgid);

  }else if( cpid > 0 ){
    /* PARRENT */

    //set the proccess group of child 
    setpgid(cpid, cpid); //<------------------!

    //print the pid, and pgid of parent
    pid = getpid();
    pgid = getpgrp();
    printf("Parent:         pid:%d pgid: %d \n", pid, pgid);    

    //print the pid, and pgid of child from parent
    cpgid = getpgid(cpid);
    printf("Parent: Child's pid:%d pgid:*%d*\n", cpid, cpgid);


  }else{
    /*ERROR*/
    perror("fork");
    _exit(1);
  }


  return 0;
}

3 Process Groups and Terminal Signaling

3.1 Foreground Process Group

  1. when we execute a pipeline, the shell will fork all the process in the job and place them in the same process group.
  2. Ctrl-c or Ctrl-z that the terminal will deliver special signals to the foreground job
  3. instead of signalling processes individually both shell and the terminal think of execution in terms of process groups.
#> sleep 10 | sleep 20 | sleep 30 | sleep 50 &
[1] 24253
#> ps
  PID TTY          TIME CMD
 4038 pts/3    00:00:00 bash
24250 pts/3    00:00:00 sleep
24251 pts/3    00:00:00 sleep
24252 pts/3    00:00:00 sleep
24253 pts/3    00:00:00 sleep
24254 pts/3    00:00:00 ps
#> fg
sleep 10 | sleep 20 | sleep 30 | sleep 50
^C
#> ps
  PID TTY          TIME CMD
 4038 pts/3    00:00:00 bash
24255 pts/3    00:00:00 ps

3.2 Orphaned Stopped Process Groups

参考:
https://www.usna.edu/Users/cs/aviv/classes/ic221/s16/lec/17/lec.html#coderef-bad_ref

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!