3

を使用するのはこれが初めての試みstd::futureです。

同時に解析したい 3 つの異なるファイルがあります。3 つの関数がそれを行います。と呼ばれるparseSentencesparseTagsおよびparseLinksstd::asyncそれらのそれぞれは、非常に単純なラムダ関数を使用し[]() { parser->function(); }て個別のスレッドで起動されますparser

int parser::start()
{
    int ret = SUCCESS;
    ASSERT( m_output != nullptr );
    static parser * thisParserInstance = this;

    // parsing files
    std::future<int> parseSentence = std::async(std::launch::async, []() { return thisParserInstance->parseSentences(); } );
    std::future<int> parseLinksResult = std::async(std::launch::async, []() { return thisParserInstance->parseLinks(); } );
    std::future<int> parseTagsResult = std::async(std::launch::async, []() { return thisParserInstance->parseTags(); } );

    // retrieving the results
    ret = parseSentence.get();
    const int linksResult = parseLinksResult.get();
    const int tagsResult = parseTagsResult.get();

    if (ret == SUCCESS)
        ret = linksResult == SUCCESS ? tagsResult : linksResult;

    return ret;
}

gdb でプログラムを実行すると、std::futureローカル変数の 1 つが破棄されるときにセグメンテーション違反が発生します。その時点で実行中のスレッドは 2 つあります。スレッド #1 のコール スタックはこちらです。スレッド #2 のコール スタックはこちらです。

最初のコール スタックのポインタthisが null であるため、セグメンテーション違反が発生することに注意してください。

誰かが手がかりを持っているなら、私は感謝します.

4

2 に答える 2

3

1 つの大きな問題がここにあります。

static parser * thisParserInstance = this;

関数を初めて呼び出したときに初期化され、その後の呼び出しでは変更されません。したがって、1 つのオブジェクトで関数を呼び出し、そのオブジェクトを破棄してから 2 番目のオブジェクトで呼び出すと、実際には機能していないオブジェクトへのダングリング ポインターを操作することになります。それは確かに未定義の動作をもたらします。

静的変数を使用する理由はありません。thisラムダは正しいオブジェクトをキャプチャして処理できます。または、コメントで提案されているように、メンバー関数asyncにバインドするために可変長形式を使用します。this

std::async(std::launch::async, &parser::parseSentences, this);
于 2012-08-27T22:17:30.563 に答える
1

申し訳ありません。

ここに解決策があります: C++0x の gcc 実験的実装に関する std::future 例外

とリンクしたら-lpthreadエラーが消えました。他のご意見とは異なりますが、大変参考になりました。

于 2012-08-27T22:36:43.690 に答える