0

コードにスレッドをプッシュしているスレッドのベクトルがあります。関数「func」を約 100 回呼び出した後、「アクティブな例外なしで呼び出されて終了します」というメッセージが表示されます。このエラーは、スレッドに対して「結合」が呼び出されていないことを意味することを読みました。以下のコードでは、ベクター内のすべてのスレッドに対して「結合」を呼び出します。私のプログラムでは、既に約 100 回関数を呼び出していますが、再度呼び出すとコードがクラッシュします。スレッド、たとえばthread_10が最初の「for」ループの終了前に終了し、2番目までに関数「join」を呼び出すことができない可能性はありますか?
可能であれば、どうすればこれを防ぐことができますか?

void func(){
    vector<std::thread> my_threads;
    for (deque<unsigned int>::iterator it = candidates.begin(); it != candidates.end(); it++)  
    {       
        Query* quer = &queries[*it];
        my_threads.push_back(std::thread(foo, param));  
    }     

    for (std::thread &thread: my_threads)
    {  
        thread.join();
    }
}
4

1 に答える 1

2

関数の最初の部分で例外がスローされた場合 (たとえば、新しいスレッドを作成するのに十分なリソースがないなどの理由で)、関数は、既に作成されたスレッドに参加することなく、例外で中止されます。おそらくこれが、アクティブな例外なしで terminate が呼び出される理由です。

以下が機能するはずです。

std::vector<std::thread> threads;
SCOPE_EXIT {
    for (auto&& thread : threads) {
        thread.join();
    }
};
for (auto&& candidate : candidates) {
    // ...
    threads.emplace_back(callable, candiate, ...);
}

編集: SCOPE_EXITはよく知られた構造であり、たとえば、愚かなライブラリのヘッダーScopeGuardで定義されています。私はこれを使用して、クリーンアップが関数 (スコープ) の最後に発生する必要があることを明確にしました。これは、関数が定期的に終了するか、例外内で終了するかにかかわらずです。

于 2013-06-19T17:27:54.537 に答える