[英]Execl() in a child process and wait() in the parent process
我不明白为什么父进程即使子进程没有终止也继续执行。
这是ac:
if (!fork()){
execl("/bin/sh", "sh", "-c", "gnome-terminal -x ./b", (char *) 0);
}
else {
int status;
wait(&status);
if ((status & 255) == 0) printf("\nProcess regularly exited ");
printf("adios");
return 0;
}
这是不列颠哥伦比亚省:
printf("hello\n");
fflush(0);
getchar();
exit(0);
当子进程尚未终止并且正在等待getchar()输入时,父进程会打印“定期退出的进程”和“ adios”,而我不明白为什么。
最后,如何强制父进程等待直到bc的执行完成?
将评论转换为答案。
面对无法按预期运行的C程序时,另一个关键问题是“ shell中发生了什么”。 对于这个问题,它转换为:当您从命令行运行sh -c "gnome-terminal …"
,要多长时间才能返回提示?
瞬间。
因此,令人惊讶的是,当您从C代码运行它时,也会发生同样的事情。 sh -c …
的外壳会立即退出,因此您的父进程会发现它的死亡并退出。 我认为您的第二个程序是作为您分叉过程的孙代或曾孙代运行的。 您有sh
,它运行gnome-terminal
,可能会分叉,而父级会退出,而孩子继续管理终端并分叉运行第二条命令的shell(或者可能不使用shell并只是执行第二条命令)。 一个进程只能等待其直接子进程死亡。 它不能等它的孩子的孩子或更远的后代。
现在,如果我在
return 0
之前的ac
末尾和exit(0)
之前的bc
末尾添加while(1){}
,则top
命令指示我有4个进程:ac
2个和bc
2个。 奇怪吗?
可能会发生多种情况。 它可能是先前运行的剩余流程。 您需要查看流程树以了解那些流程是否相关以及它们之间的关系。
谢谢,他们只是剩下的过程。
最后,如何强制父进程等待直到
bc
的执行完成?
简而言之,您不能让A等待B完成。 您需要让A知道应该等待哪个进程B的方法。 它不能直接等待它,因为B不是它自己的孩子,因此您可能最终会进行一些轮询操作以查看B是否仍在附近。 那可能是用kill()
和信号0进行测试; 在Linux上,您也许可以在/proc
文件系统上使用iNotify(并避免轮询)。
您可以使用信号。 这是一个简单但不完善的解决方案。
交流电
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <string.h>
void death_handler();
int main(){
sigset_t set;
sigfillset(&set);
sigprocmask(SIG_BLOCK,&set,NULL);
sigemptyset(&set);
sigaddset(&set, SIGUSR1);
sigprocmask(SIG_UNBLOCK, &set, NULL); //unlock SIGUSR1
signal(SIGUSR1, death_handler);
printf("my pid is %d\n", getpid());
char pid[50];
snprintf(pid, 50, "gnome-terminal -x ./b %d",(int)getpid());
if (fork() == 0){
execl("/bin/sh","sh", "-c", pid,(char *) 0);
}
else {
int status;
//nobody, apart from the other process (and anyone that sends me a SIGUSR1 signal) can tell me to exit. It has to send a SIGUSR1 signal.
pause();
//UNBLOCK ALL PREVIOUSLY BLOCKED SIGNALS
sigemptyset(&set);
sigfillset(&set);
sigprocmask(SIG_UNBLOCK, &set, NULL);
//remove ex-child handler
signal(SIGUSR1, SIG_DFL);
printf("adios\n");
return 0;
}
}
void death_handler(){
printf("ex-child dead\n");
}
这是公元前
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
int main(int argc, char** argv){
int xmax;
xmax = atoi(argv[1]);
printf("parent pid = %s \n", argv[1]);
fflush(0);
getchar();
kill((pid_t)xmax, SIGUSR1);
printf("sendinga signal to the ex-parent to abort pause()...\n");
exit(0);
}
这基本上会暂停父级,直到有人发送10信号为止。 发送SIGUSR1信号的人只能将其取消暂停。
另一个解决方案可能是使用信号量。 您将信号量初始化为0。父级执行等待,然后,子进程完成后,您只需在子级中执行一个发布,即可释放父级。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.