[英]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.