0

注意: 私は、次のコードから明らかなように、スレッドプールの操作にあまり慣れていません。このキューに多くの値をプッシュし、1 つのスレッドが完了するのを待ってから次のスレッドに移動し、システムが実行中のスレッド数の同期を処理できるという印象を受けました。

ThreadPool::QueueUserWorkItem(waitcallback, num) を使用しようとしていますが、以前のアルゴリズムに応じて num の値が動的な値まで反復されます。私が直面している問題は、プログラムが高くなりすぎるとプログラムがクラッシュすることです。

WaitCallback^ wcb = gcnew WaitCallBack(this, &createImage);
for(int i = 0; i < numBlocks; i++)
{
    ThreadPool::QueueUserWorkItem(wcb, i);
}

「ランタイム エラーです。このアプリケーションはランタイムに通常とは異なる方法で終了するよう要求しています。詳細については、アプリケーションのサポート チームにお問い合わせください。」というメッセージが表示されます。

私が最後に実行したのは numBlocks = 644 でした。

4

1 に答える 1

1

プログラムがクラッシュした原因を特定するのは困難です。最も可能性が高いのは、スレッドの 1 つで例外がスローされ、プログラムが停止したことです。コード内で例外がスローされた場所を特定する必要があります。

ご存じのとおりThreadPool::QueueUserWorkItem、スレッドプールによって処理されるアイテムをキューに入れます。ただし、そのキューからアイテムを処理する複数のスレッドが存在する可能性があります。たとえば、20 個のプール スレッドがあり、そのうちの 15 個がキューに入れられた作業項目を処理することができます。

処理する項目が非常に多く、それらを一度に 1 つずつ実行したい場合は、1 つのスレッドをキューに入れ、一度に 1 つずつ実行してみませんか。私はマネージ C++ をやったことがないので、これを使って例を書きません。しかし、おそらく次の C# コードを翻訳できます。

void ProcessInBackground(object state)
{
    int numBlocks = (int)state;
    for (int i = 0; i < numBlocks; ++i)
    {
        createImage(i);
    }
}

そして、次のように呼び出すことができます:

ThreadPool::QueueUserWorkItem(ProcessInBackground, numBlocks);

これにより、アイテムを順番に処理する単一のスレッドが作成されます。

これをマネージ C++ にかなり簡単に変換できると思います。

于 2013-03-26T14:13:30.297 に答える