web-dev-qa-db-ja.com

C ++ 11先物の使用:std :: asyncクラッシュのネストされた呼び出し:コンパイラ/標準ライブラリのバグ?

実際のプログラムでstd :: asyncのネストされた呼び出しを導入するときにクラッシュが発生した後、次の問題を再現することができました最小例。頻繁にクラッシュしますが、常にクラッシュするわけではありません。何か問題がありますか、それともコンパイラまたは標準ライブラリのバグですか?先物へのget()呼び出しが追加された場合、問題が残ることに注意してください。

#include <future>
#include <vector>

int main (int, char *[])
{
    std::vector<std::future<void>> v;
    v.reserve(100);
    for (int i = 0; i != 100; ++i)
    {
        v.emplace_back(std::async(std::launch::async, [] () {
            std::async(std::launch::async, [] { });
        }));
    }

    return 0;
}

2種類のクラッシュが発生します:(約5回の実行ごとに)

  • "このアプリケーションは、ランタイムに異常な方法で終了するように要求しました。"
  • 'std :: future_error'、what()のインスタンスをスローした後の終了:Promiseはすでに満たされています

環境:

  • Windows 7
  • gccバージョン4.8.2(i686-posix-dwarf-rev3、MinGW-W64プロジェクトによって構築)、Qt5.3.2で提供
  • コマンドライン呼び出し:g++ -std=c++11 -pthread futures.cpp
  • コンパイルされ、2台の独立したマシンで実行されます

オプション-pthread私の環境では、何らかの理由でオプション-pthreadは黙って考慮されていませんか?そのオプションがある場合とない場合で同じ動作が見られます。

55
SebastianK

この答えはまだ「未回答」なので、Lounge<C++>の何人かの人々と話した後、これは実装エラーによるものであることがコメントからかなり明らかだと思います当時のMinGW/MinGW-w64またはpthreadのいずれかの部分で。gcc 4.9.1、MinGW-W64を使用すると、問題は発生しなくなりました。実際、上記のプログラムは、POSIXスレッドを使用した4.8.2よりも古いバージョン以前でも正しくコンパイルおよび実行されているように見えます。

私自身は専門家ではありません。プログラムが同じ約束を2回書き込もうとしているように見えると、正確なトリップアップが発生すると思います。これは、std :: asyncのように大したことではないと思います。結果を1回だけ書き込む必要があります(ここでも、私がここにいるかどうかはわかりません。他のコメントや編集で明らかになる可能性があります)。

また、これは関連する問題である可能性があります: C++ 0xのgcc実験的実装に関するstd ::将来の例外

2
Cinch