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

あなたの現在のアプローチはおそらくあなたが望むことをしないでしょう。ファイル記述子を複製すると、それらはすべて同じパイプを参照します-データは複製されません。source コマンドによって送信されたデータのブロックごとに、正確に 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 に答える