在此程序中,我更改子进程的组ID。
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/wait.h>
int main(void) {
int status;
char b[4];
pid_t pid, ch_pid;
switch(pid=fork()) {
case -1:
perror("Fork failed");
exit(1);
case 0:
printf("\nCHILD: This is child process!\n");
printf("CHILD: My PID is-- %d\n", getpid());
printf("CHILD: My parent PID -- %d\n", getppid());
printf("CHILD: My GID is -- %d\n", getpgid(getpid()));
printf("CHILD: My SID is -- %d\n", getsid(getpid()));
int k = setpgid(getpid(),getpid()); /*Modifies group id. Therefore, when user press
Cn+C, ChPr can't die*/
printf("BEFORE SETPGRP CHILD: My GID is -- %d\n", getpgid(getpid()));
printf("BEFORE SETPGRP CHILD: My SID is -- %d\n", getsid(getpid()));
//read(0,b,4);
//printf("b: %s\n",b);
pause();
exit(0);
default:
printf("PARENT: This is parent process!\n");
printf("PARENT: My PID -- %d\n", getpid());
printf("PARENT: My child PID %d\n",pid);
printf("PARENT: My parent PID %d\n",getppid());
printf("PARENT: My GID %d\n",getpgid(getpid()));
printf("PARENT: My SID %d\n",getsid(getpid()));
pause();
exit(0);
}
return 0;
}
但是,当我尝试调用“ read”(带注释的字符串)时,bash终端不读取也不输出。但是,父进程正在读取成功。为什么?父子进程具有相似的会话ID。这意味着它们是由通用tty控制的。我注意到,如果我更改子进程的GID并按Cntrl + C,则父进程只会被打断,子进程将成为一个孤儿。因此,如果我取消注释程序中的“读取”并按Cntrl + C,则会杀死这两个进程。可能是不成功的读取呼叫向bash发送一些信号?谢谢!
答案 0 :(得分:1)
终端具有前景处理组设置。当外壳程序运行命令时,它将在终端的前台进程组中运行前台作业,但是后台作业将放在其自己的进程组中。只允许前台进程组从终端读取。如果后台进程尝试读取,它将被挂起;当用户将其移至前台时,将终端进程组更改为该组,继续执行该进程,然后将其读取。有stty
模式tostop
可用于控制后台进程是否可以写入终端,但是没有类似的读取选项,因此始终被禁止。
如果希望更改终端的进程组后能够从终端读取该进程,则需要更改终端的前台进程组。这是通过tcsetpgrp()
函数完成的。
tcsetpgrp(0, getpgid(getpid()));
答案 1 :(得分:0)
read(2)
仅允许用于终端前台进程组中的进程
(这是与终端驱动程序中的终端相关联的进程组)。其他进程将停止,SIGSTOP
驱动程序将信号tty
发送给它们。一些控制字符也直接指向终端控制进程组。
有关tty控件的说明,请参见termios(4)
或tty(4)
。