簡體   English   中英

如何刷新協同進程管道中的I / O緩沖區

[英]How to flush I/O buffer in coprocess's pipe

我正在使用管道來編寫協同進程。 父級創建兩個管道,一個管道用於寫入子級,另一個用於從子級讀取。 但是當我運行程序時,它正在等待,因為它將printf設置為完全緩沖為默認值。 我不想在子進程源代碼中刷新緩沖區。

我知道UNIX環境中高級編程的第19章介紹了一種使用偽終端的方法。 但我想知道是否有更多的樣本方法。 謝謝大家。

這是我的源代碼:

#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;
}

您可以使用stdbuf實用程序更改子進程的緩沖。

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM