2013-03-07 48 views
5

所以我在這裏有代碼,我期望它嚴格運行ls -l 5次,但似乎運行的次數要多得多。我在這裏做錯了什麼?我想運行ls 5次,所以我叉了5次。也許我不理解等待的概念?我花了大量的教程,而且似乎沒有人用叉子徹底解決多個過程。爲什麼我在這裏分叉5次以上?

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

int main() 
{ 
    pid_t pidChilds[5]; 

    int i =0; 

    for(i = 0; i<5; i++) 
    { 
     pid_t cpid = fork(); 
     if(cpid<0) 
      printf("\n FORKED FAILED"); 
     if(cpid==0) 
      printf("FORK SUCCESSFUL"); 
     pidChilds[i]=cpid; 
    } 





} 
+2

提示:如果cpid == 0,你認爲還有什麼你忘記了嗎? – 2013-03-07 14:43:19

+0

@NicholasWilson不是我能想到的。 (我在做什麼錯了?) – NoNameY0 2013-03-07 14:47:16

+0

Forkbomb,ftw!:D – Carsten 2013-03-07 15:24:29

回答

2

當您在C中使用fork時,您必須想象將進程代碼和狀態複製到新進程中,此時它會從停止的地方開始執行。

當您在C中使用exec時,您必須想象如果調用成功,整個過程將被替換。

這是您的代碼,重新編寫以產生預期的行爲。請閱讀評論。

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

int main() 
{ 
    pid_t cpid; 
    pid_t pidChildren[5]; 

    int i; 
    for (i = 0; i < 5; i++) 
    { 
     cpid = fork(); 
     if (cpid < 0) { 
      printf("fork failed\n"); 
     } else if (cpid == 0) { 
      /* If we arrive here, we are now in a copy of the 
       state and code of the parent process. */ 
      printf("fork successful\n"); 
      break; 
     } else { 
      /* We are still in the parent process. */ 
      pidChildren[i] = cpid; 
     } 
    } 

    if (cpid == 0) { 
     /* We are in one of the children; 
      we don't know which one. */ 
     char *cmd[] = {"ls", "-l", NULL}; 
     /* If execvp is successful, this process will be 
      replaced by ls. */ 
     if (execvp(cmd[0], cmd) < 0) { 
      printf("execvp failed\n"); 
      return -1; 
     } 
    } 

    /* We expect that only the parent arrives here. */ 
    int exitStatus = 0; 
    for (i = 0; i < 5; i++) { 
     waitpid(pidChildren[i], &exitStatus, 0); 
     printf("Child %d exited with status %d\n", i, exitStatus); 
    } 

    return 0; 
} 
+0

這個數組對於每個孩子來說都是無用的,它很快就會變成'ls'如果'cpid!= 0' at那一點,那麼我們知道我們在父進程中,這是該程序真正需要填充該數組的唯一副本。上述代碼的五份副本將在內存中創建,其中只有一份是「主工作」完成的父項。 – OregonTrail 2013-03-07 16:46:41

+0

假設您想要背靠背運行5個不同的命令,即ls,則ls -l然後pwd,爲什麼這不適合您的代碼? – NoNameY0 2013-03-07 17:09:28

+0

假設您想要背靠背運行5個不同的命令,即ls,則ls -l然後pwd,爲什麼這不適用於您的代碼? – NoNameY0 2013-03-07 17:20:30

3

您正在循環分叉並且叉準備複製包括指令指針的進程。

含義:例如,您的第一個子進程會發現自己仍然有一個循環,仍然有4輪要去

而4個流程中的每一個處理產物都會發現它必須多走3輪。

依此類推。

fork()返回您所在的進程是父進程還是子進程。如果您處於子進程中,您應該檢查該返回值並返回break;循環。

「成功時,子進程的PID在父進程中返回,0在子進程中返回。失敗時,-1在父進程中返回,未創建子進程,並且errno爲適當設置「。

所以你應該if(cpid==0) break;

+0

不是今天的120,它運行了大約15-20次。我嚴格的存儲了子進程中的pid。我怎樣才能解決我的問題?有1個子進程,並且在子進程中我存儲的pid – NoNameY0 2013-03-07 14:48:02

+0

不完全是120?不知道爲什麼,但**解決方案**已清除 – 2013-03-07 14:50:27

+1

我認爲您的計算結果不正確。進程數在每一次迭代中翻倍,所以它應該是總共1 + 2 + 4 + 8 + 16 = 31執行ls命令。 – 2013-03-07 14:57:28

0

i「日fork開始了循環裏面,所以它會運行循環的剩餘n-i迭代,遞歸分叉。

+0

我有它在循環,因爲我希望有5個叉子,他們的孩子應該將pid存儲在孩子pid數組中以便進一步工作 – NoNameY0 2013-03-07 14:49:43

+0

爲什麼downvote? – 2013-03-07 16:52:29

相關問題