我正在尝试在前台进程组中添加一个子进程。分叉后,我正在调用execve()
生成一个新进程(在本例中为 unix echo 程序)。在调用之前,execve()
我正在使用孩子的 pid 创建一个新的进程组。因此,孩子正在成为该流程组的流程领导者。之后我打电话tcsetpgrp()
在前台进程组中添加进程组。
当我运行程序时,它会挂在tcsetpgrp()
调用中。execve()
从不执行。如果我删除tcsetpgrp()
呼叫,则execve()
成功执行。
无法理解为什么会这样。以下是我写的代码:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
void pr_ids(char *name){
pid_t pid, ppid, pgid, tpgid;
pid = getpid();
ppid = getppid();
pgid = getpgrp();
tpgid = tcgetpgrp(STDIN_FILENO);
printf("%s: pid = %d ppid = %d"
" pgid = %d tpgid = %d\n", name, pid, ppid, pgid, tpgid);
}
int main(int argc, char *argv[]){
pid_t pid;
int st;
char *args[] = {"/bin/echo", "hello", NULL};
pr_ids("parent");
if((pid = fork()) == 0){
setpgid(0, 0); // creates its own process group and becomes group leader
pr_ids("child");
pid_t cpgrp = getpgrp();
tcsetpgrp(STDIN_FILENO, cpgrp); // add the process group to foreground
pr_ids("child");
execve(args[0], args, NULL);
}
else if(pid > 0){
waitpid(pid, &st, 0);
}
exit(0);
}
tcsetpgrp()
不将进程添加到进程组,而是设置终端的前台进程组。如果tcsetpgrp()
从后台进程组调用,调用进程(及其进程组中的所有进程)将从SIGTTOU
内核获得一个信号,除非被捕获,否则它将停止它们。这正是您的示例中发生的情况:您正在创建另一个进程组,然后
tcsetpgrp()
从其中调用。