3

パイプで裏打ちされたサブプロセスをフォークするための最良のテクニックは何ですか?

私の現在のプログラムは、実際にはパイプでリンクされたいくつかのコマンドである別のプロセスを実行する必要があります。コマンドが失敗または成功した場合でもコマンドの出力を知る必要がないため、fork/execを使用しています。

コマンドラインで同等のものは次のようになります

 /path/to/A arg1 arg2 | /path/to/B argB1 | /path/to/C

注:スクリプトの使用は、A / B / Cが将来変更される可能性があるため、実用的ではありません。

私が考えている2つのテクニックは次のとおりです。

  1. 再帰フォーク。次のフォークで子に使用できる親(その親への入力)出力を接続します。

  2. トップレベルですべてのパイプを作成します。
    次に、ループを使用して、パイプを適切に接続できるすべての子をフォークします。

4

2 に答える 2

1

再帰的にフォークしないでください。BをAのサブプロセスにするのは良い考えではありません。たとえば、Bがsetsid独自のセッションで実行するように呼び出すと、無関係のAが一緒に実行されます。Bが死んだ場合、AはあなたではなくSIGCHILDを取得します。特に、Bの返品ステータスを取得することはできません。

これは、一連のパイプでn人の子をフォークするためのコードのスケッチです。警告:コードをブラウザに直接入力しました。おそらく多くのタイプミスがあるので、すべてのエラーチェックを省略しました。

char *executables[n];
char *args[n];
int pipes[2*n+2]; /* child i reads from  */
int child_pids[n];
int ret; /*Error checking omitted; abort if ret ever becomes negative*/
ret = pipe(pipes);
for (i = 0; i < n; i++) {
    ret = pipe(pipes + 2 * i + 2);
    ret = fork();
    if (ret == 0) {
        /* Code of child i */
        close(pipes[2*i+1]);
        close(pipes[2*i+2]);
        dup2(pipes[2*i], 0);
        dup2(pipes[2*i+3], 1);
        ret = execv(executables[i], args[i]);
    }
    close(pipes[2*i]);
    close(pipes[2*i+3]);
    child_pids[i] = ret;
}
/* interact with the subprocesses, then call wait or waitpid as needed */
于 2012-07-19T21:42:38.837 に答える
0

UNIXを使用している場合は、シンプルでsystem("/path/to/A arg1 arg2 | /path/to/B argB1 | /path/to/C")やりたいことができます。としてシェルを呼び出します/bin/sh -c $STRING_PASSED_TO_SYSTEM。出力の読み取りや入力への書き込みなど、より詳細な制御が必要な場合popen()は、Cライブラリのルーチンを検討してください。

于 2012-07-19T20:24:05.687 に答える