2012-06-21 54 views
3

我正在使用管道來編寫協處理程序。父母創建兩個管道,一個管道用於寫入孩子,另一個管道用於從孩子讀取。但是當我運行該程序時,它會處於等待狀態,因爲它將默認設置爲完全緩衝。而且我不想在子進程源代碼中使用緩衝區。如何刷新協處理管道中的I/O緩衝區

我知道第19章高級編程在UNIX環境下引入了一種使用僞終端的方式。但我想知道是否有更多樣本來做到這一點。謝謝大家。

這裏是我的源代碼:

#include <stdio.h> 
#include <unistd.h> 
#include <string.h> 
#include <stdlib.h> 
#include <errno.h> 


int main() 
{ 
    #define MAXSIZE 1024 

    char workload[MAXSIZE]; 
    char result[MAXSIZE]; 
    char buf[10] = {0}; 
    workload[strlen(workload)] = EOF; 
    int workload_size = strlen(workload); 

    int fd1[2], fd2[2]; 
    int n; 
    pid_t pid; 
    if (pipe(fd1) < 0 || pipe(fd2) < 0) { 
     fprintf(stderr, "pipe error: %s\n", strerror(errno)); 
     exit(1); 
    } 

    if ((pid = fork()) < 0) { 
     fprintf(stderr, "fork error: %s\n", strerror(errno)); 
     exit(1); 
    } else if (pid > 0) { 
     close(fd1[0]); 
     close(fd2[1]); 
     while(fgets(workload, MAXSIZE, stdin) != NULL) 
     { 
      workload_size = strlen(workload); 
      if (write(fd1[1], workload, workload_size) != workload_size) { 
       fprintf(stderr, "write to pipe error: %s\n", strerror(errno)); 
       exit(1); 
      } 

      if ((n = read(fd2[0], result, MAXSIZE)) < 0) { 
       fprintf(stderr, "read from pipe error: %s\n", strerror(errno)); 
       exit(1); 
      } 

      if (n == 0) { 
       fprintf(stderr, "child closed the pipe\n"); 
       exit(1); 
      } 

      result[n] = 0; 

      if (puts(result) == EOF) { 
       fprintf(stderr, "fputs error\n"); 
       exit(1); 
      } 
     } 
    } else { 
     close(fd1[1]); 
     close(fd2[0]); 
     if (fd1[0] != STDIN_FILENO) { 
      if (dup2(fd1[0] ,STDIN_FILENO) != STDIN_FILENO) { 
       fprintf(stderr, "dup2 error to stdin.\n"); 
       exit(1); 
      } 
      close(fd1[0]); 
     } 
     if (fd2[1] != STDOUT_FILENO) { 
      if (dup2(fd2[1] ,STDOUT_FILENO) != STDOUT_FILENO) { 
       fprintf(stderr, "dup2 error to stdout.\n"); 
       exit(1); 
      } 
      close(fd2[1]); 
     } 

     if (execl("./a.out", "a.out", NULL) < 0) { 
      fprintf(stderr, "execl error: %s\n", strerror(errno)); 
      exit(1); 
     } 
     exit(0); 
    } 

    return 0; 
} 

從標準輸入和輸出,它只是讀取的子進程:

#include <stdio.h> 

int main() 
{ 
    #define MAXSIZE 1024 
    char x[MAXSIZE]; 
    int n; 
    while(fgets(x, 1024, stdin) != NULL) 
    { 
     printf("%s", x); 
    } 
    return 0; 
} 

回答

2

可以使用stdbuf工具來改變你的子進程的緩衝。

或者,如果您可以更改子進程的代碼,請直接從子進程調用setvbuf

+0

它確實是一個整潔的方式。謝謝! –

+0

我想知道是否可以直接在源代碼中更改管道的緩衝區? –

+0

已更新,請使用'setvbuf' –