2013-11-23 211 views
0

我寫了一個管道10個整數,所以我打電話寫10次,然後我想調用讀管道一次,並將寫入的整數存儲到大小爲10的數組中,然後添加所有整數從數組變成總數。問題是閱讀後我只能得到9個整數。我做錯了什麼?從管道問題讀取

int main() 
{ 
    int fd[2]; 
    int total = 0; 
    int result; 
    int nbytes; 
    int child; 
    int subVector; 
    int written; 
    static int readSum[P]; 
    int partialSum; 
    if(pipe(fd) < 0){ 
     perror("pipe"); 
    } 

    for(child = 0; child < P; child++){ 
     if((pid[child] = fork()) < 0){ 
      perror("fork"); 
      exit(1); 
     } 
     else if(pid[child] == 0){ 
      close(fd[0]); 
      partialSum = getSubvectorSum(elementsList,child,P,SIZE); 
      //printf("Partial sum: %d by child #%d\n",partialSum,getpid()); 
      written = write(fd[1],&partialSum,sizeof partialSum); 
      //printf("Child #%d has written: %d bytes.\n",getpid(),written); 
      if(written == 0){ 
       printf("Writting not performed."); 
      } 
      close(fd[1]); 
      exit(0); 
     } 
    } 

    close(fd[1]); 
    int status = 0; 

    nbytes = read(fd[0],&readSum,sizeof readSum); 
    printf("Parent reads %d bytes\n",nbytes); 
    if(nbytes > 0){ 
     for(child =0;child<P;child++){ 
      total += readSum[child]; 
      printf("Partial sum in father: %d\n",readSum[child]); 
     } 
    } 
    else{ 
     printf("Failed to read."); 
    } 
} 
+0

如果您使用非阻塞IO,請調用讀入週期。 – Basilevs

+0

我用週期閱讀,一切都很好,但我很好奇:爲什麼不這樣工作? – laura

+0

什麼是'static int readSum [P] = NULL;'應該是? – glglgl

回答

1

你忽略了鼠尾草滾石的智慧,不接受你不能總是得到你想要的東西,但有時你得到你所需要的東西。

(1)在父母試圖閱讀之前,並不能保證所有的孩子都已經跑到管道上。 (2)即使(1)確實發生了你的閱讀會在一次閱讀中返回全部10個整數,也不能保證。 read可以(並且通常會)返回比您要求的更少。

解決這個問題的一種方法是讓您的父母wait位於其子女身上,以便您知道他們已完成,然後以循環方式閱讀,直到閱讀完所需內容。

+0

通過這種方法,一個循環就足夠了 - 如果沒有數據,讀取將會被阻塞,但是請求的數量會更多。 – Basilevs

+0

順便說一句,爲什麼答覆不交錯?同時寫入是否受到保護? – Basilevs

+0

@Basilevs,是的。我認爲等待會更好地說明爲什麼一切都不會在一次閱讀中被吞噬。在fd上的管道寫入是原子寫入PIPE_BUF長度的。 – Duck