2012-10-25 29 views
0

循環應該中斷,但它仍然卡在fgets上。 process_P1通過管道與inputHandler對話。問題是inputHandlerprocess_P1停止寫入時沒有意識到...'lalala'printf永遠不會到達。fgets在C中不返回NULL

void process_P1(char *argv[], int fd[2], pid_t child) 
{ 
    int bytes = 0; 

    static char bufferIn[BUFFER_SIZE]; 
    static char bufferOut[BUFFER_SIZE]; 

    char line[BUFFER_SIZE]; 

    // close reading end of pipe 
    close(fd[0]); 

    FILE *in = fopen(getInput(argv), "r"); 
    FILE *out = fdopen(fd[1], "w"); 

    if (in == NULL) { 
      sys_err("fopen(r) error (P1)"); 
    } 
    int ret = setvbuf(in, bufferIn, _IOLBF, BUFFER_SIZE); 
    if (ret != 0) { 
      sys_err("setvbuf error (P1)"); 
    } 

    if (out == NULL) { 
      sys_err("fdopen(w) error (P1)"); 
    } 
    ret = setvbuf(out, bufferOut, _IOLBF, BUFFER_SIZE); 
    if (ret != 0) { 
      sys_err("setvbuf error (P1)"); 
    } 

    while (fgets(line, BUFFER_SIZE, in) != NULL) 
    { 
      fprintf(out, "%s", line); 
      bytes += count(line) * sizeof(char); 
    } 

    // alert P2 to stop reading 
    //fprintf(out, "%s", STOP); 

    fclose(in); 
    fflush(out); 
    fclose(out); 

    printf("P1: file %s, bytes %d\n", getInput(argv), bytes); 

    // wait P2 ends 
    if (waitpid(child, NULL, 0) < 0) { 
      sys_err("waitpid error (P1)"); 
    } 
} 

void *inputHandler(void *args) 
{ 
    int ret; 

    static char bufferIn[BUFFER_SIZE]; 
    char line[BUFFER_SIZE]; 
    struct node *iterator; 

    int *fd = (int*)args; 

    close(fd[1]); 

    FILE *in = fdopen(fd[0], "r"); 
    if (in == NULL) { 
      sys_err("fdopen(r) error (P2)"); 
    } 
    ret = setvbuf(in, bufferIn, _IOLBF, BUFFER_SIZE); 
    if (ret != 0) { 
      sys_err("setvbuf(in) erro (P2)"); 
    } 

    while (fgets(line, BUFFER_SIZE, in) != NULL) 
    { 
    //  printf("%s", line); 
      iterator = firstArg; 
      while (iterator->next != NULL) 
      { 
        ret = sem_wait(&(iterator->sem)); 
        if (ret == 0) { 
          strcat(iterator->buffer, line); 
        } else { 
          sys_err("sem_wait error"); 
        } 
        ret = sem_post(&(iterator->sem)); 
        if (ret != 0) { 
          sys_err("sem_post error"); 
        } 
        iterator = iterator->next; 
      } 
      line[0] = '\0'; 
    } 
    printf("lalala\n"); 
    iterator = firstArg; 
    while (iterator->next != NULL) 
    { 
      ret = sem_wait(&(iterator->sem)); 
      if (ret != 0) { 
        sys_err("sem_wait error"); 
      } 
      iterator->shouldStop = 1; 
      ret = sem_post(&(iterator->sem)); 
      if (ret != 0) { 
        sys_err("sem_post error"); 
      } 
      iterator = iterator->next; 
    } 

    fclose(in); 

    return NULL; 
} 

回答

1

該問題可能不在您顯示的代碼中。既然你提到了一個管道,你的問題可能在於與管道相關的管道 - 而且很可能你在管道的一端做了一個dup2(),使它成爲標準輸入或標準輸出,但是你忘記關閉文件描述符你複製了,或者你忘了關閉另一端。在沒有可寫入正在讀取的管道的進程之前,fgets()不會終止。如果正在讀取的進程仍然打開管道的寫入結束,它將一直停留在讀取中,等待它寫入​​內容。

所以,看看你的管道代碼很難。在將一端複製到標準輸入或標準輸出後,確保已關閉由pipe()返回的值。

+0

謝謝你。我也用叉子在我的程序中。其中一個叉克隆了管道描述符,這意味着管道在子進程中打開。現在我在叉子前關閉管道,它工作正常! –