1

我在linux下使用popen执行命令,然后4个进程使用相同的输出。我试图再次复制文件描述符以将其传递给每个进程。这是我的代码:

FILE* file_source = (FILE*) popen(source_command, "r");
int fd = fileno(file_source);
fdatasync(fd);

int dest_fd[4], y, total = 4;
    for (y = 0; y < total; y++) {
        dest_fd[y] = dup(fd);
    }

实际上,如果将 total 设置为 1 它工作正常,在更改 total = 4 后它不再工作。这个答案太接近我需要的: 链接

4

2 回答 2

1

您当前的方法可能无法满足您的要求。当您只是复制文件描述符时,它们都引用同一个管道 - 没有数据会被复制。对于源命令发送的每个数据块,只有一个进程将读取它。

如果你想复制数据(就像tee实用程序一样),那么你需要明确地这样做:

#define TOTAL 4

int dest_fd[TOTAL];
int dest_fd_wr[TOTAL];
int y;

/* Build pipes for reading the data from the child process */
for (y = 0; y < TOTAL; y++)
{
    int p[2];

    pipe(p);
    dest_fd[y] = p[0];
    dest_fd_wr[y] = p[1];
}

/* Create a child process to handle the "tee"-style duplication */
if (fork() == 0)
{
    /* Child process */
    FILE *file_source = popen(source_command, "r");
    FILE *file_sink[TOTAL];
    char buffer[2048];
    size_t nbytes;

    for (y = 0; y < TOTAL; y++)
    {
        close(dest_fd[y]);
        file_sink[y] = fdopen(dest_fd_wr[y], "w");
    }

    while ((nbytes = fread(buffer, 1, sizeof buffer, file_source)) > 0)
    {
        for (y = 0; y < TOTAL; y++)
        {
            fwrite(buffer, 1, nbytes, file_sink[y]);
        }
    }

    _exit(0);
}

for (y = 0; y < TOTAL; y++)
{
    close(dest_fd_wr[y]);
}

/* Now have a set of file descriptors in dest_fd[0..TOTAL-1] that each have
 * a copy of the data from the source_command process. */

错误处理留给读者练习;)

于 2010-05-07T02:53:11.310 回答
0

通过阅读您链接到的问题,它似乎在谈论dup()并创建一个完全独立的新文件描述符(它们不共享文件偏移量)。如果这是您想要的,您需要按照他们在问题中的建议进行操作。

您需要根据需要多次打开/重新打开输出。看起来他们通过打开输出定向到的新文件来解决限制。我的猜测是,您只需将 source_command 的输出重定向到一个文件,然后多次打开输出文件,而不是使用dup().

于 2010-05-06T12:30:44.130 回答