0

私の要件は単純です。プロセスを開始し、終了するのを待ってから、その出力をキャプチャして処理します。

長い間、私は次のものを使用してきました。

struct line : public std∷string {
    friend std∷istream& operator>> (std∷istream &is, line &l) {
        return std∷getline(is, l);
    }
};

void capture(std::vector<std::string> &output, const char *command)
{
    output.clear();
    FILE *f = popen(command, "r");
    if(f) {
        __gnu_cxx::stdio_filebuf<char> fb(f, ios∷in) ;
        std::istream fs(&fb);
        std::istream_iterator<line> start(fs), end;
        output.insert(output.end(), start, end);
        pclose(f);
    }
}

また、シングル スレッド プログラムでは非常にうまく機能します。

ただし、スレッド内からこの関数を呼び出すと、popen()呼び出しがハングして返されないことがあります。

したがって、概念実証として、この醜いハックの関数を置き換えました。

void capture(std::vector<std::string> &output, const char *command)
{
    output.clear();
    std::string c = std::string(command) + " > /tmp/out.txt";
    ::system(c.c_str());
    ifstream fs("/tmp/out.txt", std::ios::in);
    output.insert(output.end(), istream_iterator<line>(fs), istream_iterator<line>());
    unlink("/tmp/out.txt");
}

醜いですが機能しますが、マルチスレッドプログラムでプロセス出力をキャプチャする適切な方法は何だろうと思っていました。

このプログラムは、組み込み powerquiccII プロセッサの Linux で実行されます。

4

1 に答える 1

2

これを参照してください:popen - ロックまたはスレッドセーフではありませんか? および他の参照は、 popen() がスレッドセーフである必要があることを決定的にしていないようです。おそらく、あまり人気のないプラットフォームを使用しているため、実装はそうではありません。お使いのプラットフォームの実装のソース コードを表示できる可能性はありますか?

それ以外の場合は、新しいプロセスを作成して待機することを検討してください。またはねえ、ばかげた system() ハックに固執しますが、その戻りコードを処理してください!

于 2013-02-27T11:26:32.160 に答える