2010-10-13 16 views
0

我在寫一個僞shell程序,它從父進程創建一個子進程。父進程在繼續之前等待孩子完成。我的分叉代碼看起來是這樣的:C - 僞shell和併發

if(fork()==0) 
{ 
    execvp(cmd, args); 
} 
else 
{ 
    int status = 0; 
    wait(&status); 
    printf("Child exited with status of %d\n", status); 
} 

但是,我希望能夠解析「&」操作,這樣如果用戶在命令行的末尾進入它,父母也不會在提示用戶輸入其他命令之前等待孩子。我添加了一些代碼來處理這個問題,但我不確定它是否正確。它看起來是這樣的:

if(fork()==0) 
{ 
    execvp(cmd, args); 
} 
else 
{ 
    if(andOp = 1) //boolean to keep track of if '&' was encountered in parsing 
    { 
     shellFunc(); //main function to prompt user for a cmd line 
    } 
    int status = 0; 
    wait(&status); 
    printf("Child exited with status of %d\n", status); 
} 

這是否真的實現了由常規shell實現的併發性?

回答

2

小心轉讓,而不是比較。

當心未能執行命令 - exit(1);execvp()之後。

我想我會用:

if (andOp == 0) 
{ 
    int status; 
    int corpse = wait(&status); 
    printf("Child %d exited with status 0x%04X\n", corpse, status); 
} 

也就是說,我只能等待,如果「&」失蹤了。

但是,隨着背景孩子隨機死亡,你需要跟蹤後臺進程,尤其是你需要在wait()上循環,直到你剛剛分叉的孩子死亡。因此您還需要從fork()中捕獲該PID。

您可能希望在收集您正在等待的孩子後使用waitpid(),使用非阻塞選項清理任何其他身體,以便在沒有這樣的孩子時立即返回。您仍然可以在循環中使用它,這樣,如果完成了6個後臺作業,則可以將它們全部收集起來。

此外,您可以考慮忽略「兒童死亡」(SIGCHLD)信號 - 並讓系統照顧他們。但是,一個shell通常會在其中一個後臺作業完成時進行報告。

0

兩個問題:

  • 如果什麼EXEC失敗?
    • 你應該殺了孩子
  • 如果什麼信號發生在家長嗎?
    • 等待退出。你需要檢測並重新等待。
  • 調用ShellFunc()遞歸調用沒有幫助,因爲沒有實際的退出策略。
    • 使用int sigaction()來檢測後臺任務上的子故障。