2010-09-18 163 views
0

我在進行分叉練習時遇到問題。我想分叉一個子進程,並在聲明它已經分叉後讓它掛起,等待一個信號終止,之後父進程必須宣佈它正在終止然後退出。在C中終止子進程後,父進程未完成

我可以得到進程分叉,並讓父母等待懸掛的孩子被信號殺死,但它似乎也殺死了父母。我試圖通過PID來殺死兒童進程,但沒有成功。

感謝您的幫助!

代碼:

#include <stdio.h> 
#include <signal.h> 
#include <unistd.h> 
#include <stdlib.h> 
#include <sys/wait.h> 
#include <sys/types.h> 


void catchInt (int signum) 
{ 
    printf("\nMy sincerest apologies, master\n"); 
    /*kill(0, SIGINT);*/ 
    exit(0); 
} 

void ignoreInt (int signum) 
{ 
    wait(NULL); 
} 

int main() { 

    pid_t pid; 

    /* fork process */ 
    pid = fork(); 
    if (pid < 0) /* error handler */ 
    {  
     fprintf(stderr, "Fork Failed"); 
     exit(-1); 
    } 

    else if (pid == 0) /* child */  
    { 
     printf("Child reporting in\n"); 
     signal(SIGINT, catchInt); 
     for (;;) 
      pause(); 
    } 

    else /* parent */ 
    { 
     /* parent will wait for the child to complete */ 
     signal(SIGINT, ignoreInt); 
     wait(NULL); 
     printf("You're welcome\n"); 
     exit(0); 
    } 

} 
+1

您顯示的代碼無法編譯 - 您尚未定義tempPID。你不需要''兩次,而現在你不需要''(儘管在一些早期版本的POSIX中,它是需要的)。 – 2010-09-18 20:23:00

+1

這不能編譯,即使它做了也沒什麼意義。 'tempPID'完全沒有聲明,並且只在父進程中使用的信號處理程序中讀取,儘管它只在子進程中設置。至少解決這個問題,我們會看到我們可以從那裏獲得你的位置。 – 2010-09-18 20:24:43

回答

3

即使假設你修復代碼,以便它編譯(你沒有定義tempPID),有問題:

  • 您可以設置孩子去睡覺,直到信號到達。
  • 您設置父級要等到孩子死亡。

所以,你有一個狀態,任何進程都不會做更多的事情。

你可能需要家長到的信號發送到孩子:

kill(pid, SIGINT); 
  • 目前尚不清楚,你需要家長設置的信號處理程序。
  • 您可能希望孩子設置信號處理程序。
  • 你可能不想在孩子的無限循環。
  • 噢,和void main()是不正確的 - int main()int main(void)int main(int argc, char **argv)main()的批准聲明。
  • 如果你從main()返回一個值(0),它是整潔的。 C99標準確實允許你放棄main()的結尾,並將其視爲返回零,但前提是該函數正確聲明爲返回int
  • wait()的標題和POSIX中的親屬是<sys/wait.h>

而且,因爲我是個傻逼,下面是編譯,甚至可能做你想要的代碼:

#include <stdio.h> 
#include <signal.h> 
#include <unistd.h>   /* getpid() */ 
#include <stdlib.h> 
#include <sys/wait.h> 

void catchInt(int signum) 
{ 
    printf("Child's PID is %d\n", (int)getpid()); 
    printf("My sincerest apologies, master\n"); 
    exit(1); 
} 

int main() 
{ 
    pid_t pid = fork(); 
    if (pid < 0) /* error handler */ 
    {  
     fprintf(stderr, "Fork Failed"); 
     exit(-1); 
    } 
    else if (pid == 0) /* child */  
    { 
     printf("Child reporting in\n"); 
     signal(SIGINT, catchInt); 
     pause(); 
    }  
    else /* parent */ 
    { 
     sleep(1); 
     kill(pid, SIGINT); 
     wait(NULL); 
     printf("You're welcome\n"); 
    } 
    return(0); 
} 
+0

我整理了代碼,tempPID是嘗試用不同方法殺死孩子的剩餘廢料。兩個進程無限循環的原因是他們正在等待SIGINT信號通過按CTRL + C發送,我應該澄清。還有Johnathan,如果沒有sys/types.h來傳遞pid_t的原型,代碼將無法編譯。 – JKomusin 2010-09-18 20:52:42

+0

@Josh:你在哪個環境中運行,仍然需要明確的''?我很久沒有遇到過這樣的機器 - 至少五年。但是,正如我在最初的評論中指出的那樣,有一次POSIX標準或[Single UNIX Specification 1997](http://www.opengroup.org/onlinepubs/007908799/xsh/getpid.html)標準要求。 – 2010-09-19 00:49:11

0

只是想出了什麼,我做錯了,我應該意識到SIGINT被髮送到每個進程,所以父進程只是被髮送一個未處理的SIGINT,導致它退出。感謝所有的幫助(我對草率編碼的歉意,我真的不應該等到程序完成清理之後),代碼已經在上面進行了編輯並按預期工作。

再次感謝。