2015-10-05 199 views
0

我有一個程序,在循環中創建幾個fork()之後,在父進程之後執行所有子進程。 但相反,父進程在每個子進程終止之前運行。所有子進程終止後,無法運行父進程。

im childprocess : 18389 
parent process done 
im childprocess : 18390 
parent process done 
im childprocess : 18391 
parent process done 

這裏是我用叉子()的代碼調用

for (int file = 0; file < files_count; file++) { 
     pid_t pid = fork(); 
     int file_loc = file + 2; 

     if (pid == 0) { 
      // child process 
      occurrences_in_file(argv[file_loc], argv[1]); 
      break; 
     } else if (pid > 0) { 
      // parent process 
      parentProcess(); 
     } else { 
      // fork failed 
      printf("fork() failed!\n"); 
      return 1; 
     } 

    } 

void occurrences_in_file(const std::string& filename_, 
     const std::string& pattern_); 
void occurrences_in_file(const std::string& filename_, 
     const std::string& pattern_) { 
    int my_pid; 





    cout << "im childprocess : " << my_pid <<endl; 

} 

void parentProcess(); 
void parentProcess() { 

    while (true) { 
     int status; 
     pid_t done = wait(&status); 
     if (done == -1) { 
      if (errno == ECHILD){ 

       cout << "parent process done"<< endl; 
       break; // no more child processes 
      } 
     } else { 
      if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) { 
       std::cerr << "pid " << done << " failed" << endl; 
       _exit(1); 
      } 
     } 

    } 


} 

回答

1

在這裏,您正在循環的每次迭代中創建一個子進程,然後在同一次迭代中等待它。因此,在一次迭代結束時,會創建一個子進程,然後打印然後退出,父進程從等待中喚醒並打印出來,從而得到前兩行。

接下來的迭代會出現類似的輸出,因此您會爲循環的每次迭代獲取兩行,它看起來像父節點在子節點之前執行,但它不是。

如果您想在所有子進程完成後調用父進程,請執行以下操作。

引入一個全局變量isParent,如果當前進程是父進程,則爲true。其初始化爲零

int isParent = 0; 

然後在循環中,而不是調用parentProcess()設置isParent1

for (int file = 0; file < files_count; file++) { 
    pid_t pid = fork(); 
    int file_loc = file + 2; 

    if (pid == 0) { 
     // child process 
     occurrences_in_file(argv[file_loc], argv[1]); 
     break; 
    } else if (pid > 0) { 
     // parent process 
     isParent = 1; 
    } else { 
     // fork failed 
     printf("fork() failed!\n"); 
     return 1; 
    } 

} 

然後for循環調用parentProcess如果isParent設置

if(isParent){ 
    ParentProcess(files_count) 
} 

,然後進行在parentProcess(int numChildren)調用中等待所有的子進程。

void parentProcess(int numChildren); 
void parentProcess(int numChildren) { 

while (true) { 
    int status; 
    int i; 
    for(i = 0;i < numChildren; i++){ 
     pid_t done = wait(&status); 
     if (done == -1) { 
      if (errno == ECHILD){ 

       cout << "parent process done"<< endl; 
       break; // no more child processes 
      } 
     } else { 
      if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) { 
       std::cerr << "pid " << done << " failed" << endl; 
       _exit(1); 
      } 
     } 
    } 
} 
+0

我知道它在孩子之後執行。但我嘗試的是在所有childs之後執行它,以便輸出如下所示:im childprocess:18389 \ n im childprocess:18390 \ n im childprocess:18391 \ n父進程已完成... – LxSwiss

+0

您編寫的代碼的作用是不這樣做。正如我所說,這段代碼在每次迭代中產生一個新的子代,並且父代等待那個子代完成,然後在下一次迭代中產生另一個子代。這也是爲什麼'父進程完成'被打印三次而不是一次。如果您想要在最後打印「完成父進程」,請按照我的編輯進行操作 – Nishant

相關問題