2012-04-15 78 views
8

我正在編寫一個mapreduce程序,它使用多個I/O管道(每個進程一個管道)來獲得最終結果。我在創建流程時遇到問題。具體來說,我收到以下錯誤:fork() - 多個進程和系統調用

wait error: Interrupted system call 

這是我的代碼產生進程:

while (values[inc]!=NULL) //provided array of text lines 
{ 
    if ((pid = fork()) == -1) { 
     perror("fork error"); 
     exit(EXIT_FAILURE); 
    }  

    else if (pid == 0) {    /* start of child process  */ 
     printf("Child process...\n"); 
     /* pipes[inc][1] is a file descriptor to which myMap writes some data 
      using the write() system call 
      mr is a struct that holds other function pointers */ 
     mr->myMap(pipes[inc][1],values[inc]); 
     exit(0); 
    } 
    else {       /* start of parent process  */ 
     printf("Parent process...\n"); 

     if ((wpid = wait(&status)) == -1) 
     /* Wait for child process.  */ 
      perror("wait error"); 
     else {      /* Check status.    */ 
      if (WIFSIGNALED(status) != 0) 
       printf("Child process ended because of signal %d\n", 
         WTERMSIG(status)); 
      else if (WIFEXITED(status) != 0) 
       printf("Child process ended normally; status = %d\n", 
         WEXITSTATUS(status)); 
      else 
       printf("Child process did not end normally\n"); 
     } 
     //close(fd[1]); 

     printf("Parent process ended\n"); 
    } 
    inc++; 
} 

在此之後,我創建一個線程

pthread_t newThread; 
pthread_create(&newThread,NULL,threadFunction,values); 
pthread_join(newThread,NULL); 

的threadFunction使用select( )函數來查找哪個文件描述符已準備好被讀取並讀取它並將數據放入字典中。

當運行形式gdb調試器,程序輸出:

Parent process... 
Child process... 
wait error: Interrupted system call 
Parent process ended 
Parent process... 
Child process ended normally; status = 0 
Parent process ended 
Parent process... 
Child process... 
Child process... 
wait error: Interrupted system call 
Parent process ended 

我不知道如何解決這個問題。有什麼建議麼?

謝謝!

回答

9

您需要將wait()調用放入循環中,如果它返回錯誤(-1)並且errno == EINTR繼續循環。任何其他錯誤都是一個真正的錯誤,應該這樣對待。

之類的東西剖析定時器可導致信號被髮送到進程,但是信號可能導致中斷爲SIGCHLD,因爲你知道,當一個子進程改變狀態被稱爲其。

編輯:好的,我會寫的答案代碼:

do 
{ 
    wpid = wait(&status); 
} 
while (wpid == -1 && errno == EINTR); 
if (wpid == -1) 
{ 
    perror("wait error"); 
    return -1; 
} 
else 
{ 
    // we have wait status 
    ... 
} 
+0

我不知道你的意思。請詳細說明。 – Krzysiek 2012-04-15 08:48:44

+1

@Rafcio我已經更新了我的答案。 – trojanfoe 2012-04-15 08:53:40

+1

謝謝。這說得通! :) – Krzysiek 2012-04-15 09:01:50