0

これが私の状況を説明するための疑似コードです。QThreads を使用していますが、解決策は Qt に依存しない場合があります。

class ResourceOwner
{
  // Spawns worker on new QThread, initiates Worker::doWork()
 void spawnWorker(resource); {...}

 void deleteResourceSafely(); // How do you implement this function?

private:
 Resource *resource;
 Worker *worker;
}

class Worker
{
 void doWork() { while(true) resource->doSomething(); }
 void cleanupSelf() {...};
private:
 Resource *resource;
}

void main()
{
  ResourceOwner owner();
  owner.spawnWorker();
  ...
  // Some time later after enough work has been done
  owner.deleteResourceSafely();
}

削除するときはresource、ワーカーをシャットダウンする必要があります。ただし、 はWorkerにアクセス中の可能性がありますresource

resourceを削除しただけでは、無効Workerなメモリにアクセスするためクラッシュします。Workerが属するスレッドを停止することはできますが、Worker適切にクリーンアップする機会はありません。

Workerでは、の機能を中断doWork()して、自分自身をクリーンアップし、アクセスを停止するように指示するにはどうすればよいresourceでしょうか。

4

3 に答える 3

1

一般的で簡単な方法は、スレッドが定期的にチェックするフラグを設定することです。設定されている場合、スレッドはそれ自体を終了します。

于 2013-07-12T21:58:12.797 に答える
0

すでに Qt を使用していることを考えると、リソースを削除しようとしているスレッドがワーカー スレッドにシグナルを送信し、シグナルの結果としてワーカー スレッドが終了するのを待つことをお勧めします。明らかに、適切なシグナル ハンドラを実装する必要があります。

于 2013-07-12T22:08:31.377 に答える
0

joachim が述べたように、ワーカー スレッドで定期的にチェックするフラグがあります。スレッドが run () を終了する必要があることを示すために、volatile bool または QAtomicInt を false に設定する requestStop のような関数を Worker に追加します。volatile bool を使用して、コンパイラがアクセスを最適化しないようにします。作業項目はこのフラグを頻繁にチェックする必要があり、それが false になった場合は、run () からできるだけ早く戻るようにする必要があります。言及されていないのは、フラグを設定した後、スレッドで wait () を呼び出して終了することです。wait() への呼び出しが返されると、スレッドが停止したため、リソースを安全に削除できます。

部分的な代替手段は、参照カウント リソースを使用して、wait() の呼び出しを回避することです。リソースがワーカー スレッド内にリソースへの共有ポインターを持っている場合、メイン スレッドがリソースへの参照を削除し、スレッド (または作業項目) に完了フラグを立てると、ワーカー スレッド/項目は完了時にリソースへの参照を削除して破棄できます。それが唯一の残りの所有者である場合。つまり、このアプローチは、代わりに作業項目がキューに入れられるため、スレッドが完了するのを待たないスレッドプールで機能します。

于 2013-07-12T22:35:25.033 に答える