2016-03-20 28 views
0

我對管道和併發性有點新,並且幾個小時一直對此問題感到沮喪。我很難理解爲什麼這個write操作在我的管道上不斷失敗。我試圖讓子進程通過父進程接收的管道寫入數據。我當前的代碼是這樣的:管道上的寫入操作始終是失敗的

#include <unistd.h> 
#include <stdio.h> 
#include <stdlib.h> 
#define MAXSIZE 4096 

int main() { 
    pid_t status; 
    int fd[2]; //The array of file descriptors 

    if (pipe(fd) == -1) { 
     printf("Error piping"); 
    } 

    status = fork(); //Begin the fork process 
    switch (status) { 
     case -1: 
      perror("Error forking"); 
      break; 
     case 0: 
      //Child process 
      close(fd[0]); //Only send data 
      char some_string[15] = "hi there"; 
      if (write(fd[1], some_string, MAXSIZE) == -1) { 
       printf("Error writing to the pipe"); 
      } 
      close(fd[1]); //Close write end 
      exit(1); 
     default: 
      close(fd[1]); //Only receive data 
      char readed[500] = ""; 
      while(read(fd[0], readed, MAXSIZE) != 0) { 
       printf("read this %s\n", readed); 
      } 
      printf("Done reading"); 
      close(fd[0]); 
      break; 
    } 
    return 1; 
} 

不過,我不斷收到消息「錯誤寫入管道」,這意味着write操作失敗的子進程。另一個有趣的事情是,如果我將some_string更改爲字符串文字,此代碼可正常工作,但它永遠不會終止,相反,父進程中的read操作將從STDIN讀取!我不明白爲什麼會發生這種情況,當父母執行時,我們是否有殭屍小孩,所以管道「死亡」?或者,也許父進程終止,我們有一個孤兒?我該如何避免這種情況,以及如何解釋字符串文字中的奇怪行爲呢?任何見解?

回答

2

您告訴write()讀取數組超出範圍的數據,並允許read()將讀取的數據寫入陣列的超出範圍。這非常糟糕。

只寫入有效數據並限制讀取的長度不會導致超出範圍的訪問。

試試這個:

#include <unistd.h> 
#include <sys/types.h> /* add this to use pid_t */ 
#include <sys/wait.h> /* add this to use wait() */ 
#include <stdio.h> 
#include <stdlib.h> 
/* remove unused MAXSIZE */ 

int main() { 
    pid_t status; 
    int fd[2]; //The array of file descriptors 
    int st; /* variable for receiving the status */ 

    if (pipe(fd) == -1) { 
     printf("Error piping"); 
     return 1; /* return 1 when the execution failed */ 
    } 

    status = fork(); //Begin the fork process 
    switch (status) { 
     case -1: 
      perror("Error forking"); 
      return 1; /* return 1 when the execution failed */ 
      break; 
     case 0: 
      //Child process 
      close(fd[0]); //Only send data 
      char some_string[15] = "hi there"; 
      if (write(fd[1], some_string, sizeof(some_string)) == -1) { 
       printf("Error writing to the pipe"); 
      } 
      close(fd[1]); //Close write end 
      exit(0); /* return 0 if the execution finished successfully */ 
     default: 
      close(fd[1]); //Only receive data 
      char readed[500] = ""; 
      while(read(fd[0], readed, sizeof(readed) - 1) != 0) { /* -1 for reserving space for terminating null-character */ 
       printf("read this %s\n", readed); 
      } 
      printf("Done reading"); 
      close(fd[0]); 
      wait(&st); /* wait for the child process to exit and release the data of the process */ 
      break; 
    } 
    return 0; /* return 0 if the execution finished successfully */ 
} 
+0

這本來是很容易通過更換'printf的發現(「錯誤寫入管」);(「錯誤寫入管道」)'和'PERROR;'這將會打印出'EFAULT'。 – EOF

+0

由於在我的'readed'數組中大於我指定的'4096'字節宏? –

+0

@PhilipTsang精益數學。 '500'明顯小於'4096','sizeof(char)'被定義爲'1'。 – MikeCAT