popen 后重复的文件描述符

发布于 2024-08-31 08:55:46 字数 482 浏览 5 评论 0原文

我正在使用popen在linux下执行命令,然后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);
    }

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

I am using popen to execute a command under linux, then 4 process wile use the same output.
I am trying to duplicate the file descriptor again to pass it to each process.
here is my code:

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

actually if total set to 1 it work fin, after changing total = 4 it does not work anymore.
this answer is too close to what i need:
link

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

寻梦旅人 2024-09-07 08:55:46

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

如果您想复制数据(就像 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. */

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

Your current approach probably won't do what you want. When you just duplicate the file descriptors, they all refer to the same pipe - no data is going to get duplicated. For each block of data sent by the source command, exactly one process is going to read it.

If you want to duplicate the data (like the tee utility does), then you will need to explicitly do so:

#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. */

Error-handling is left as an exercise for the reader ;)

无敌元气妹 2024-09-07 08:55:46

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

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

From reading the question you linked to, it seems to be talking about dup() and creating a new file descriptor that is completely separate from eachother (they don't share file offset among other things). If this is what you want, you'll need to do what they suggest in the question.

You'll need to open/reopen the output as many times as you'd like to have duplicates. It looks like they work around the limitation by opening a new file which the output is directed to. My guess is that you simply need to redirect the output of the source_command to a file and then open the output file multiple times rather than using dup().

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文