3

作業項目のキューを処理するワーカー スレッドがあります。作業項目は現在処理できない可能性があるため、ワーカー スレッドがそれらをキューにプッシュする可能性があります。

void* workerFunc(void* arg) {
    WorkItem* item = NULL;

    while(true) {
        {
            scoped_lock(&queueMutex);
            while(workerRunning && workQueue.empty())
                pthread_cond_wait(&queueCondition, &queueMutex);
            if(!workerRunning)
                break;

            item = workQueue.front();
            workQueue.pop();
        }

        // process item, may take a while (therefore no lock here),
        // may also be considered unprocessable

        if(unprocessable) {
            scoped_lock(&queueMutex);
            workQueue.push(item);
        }
    }
    return NULL;
}

今、私は次のことを行う必要があります: 時々、作業キューをスキャンして、不要になったアイテムを削除する必要があります (作業アイテムをエンキューする同じスレッドから)。現在処理中のアイテムを見逃す可能性があるため、これには queueMutex を使用できません。そのため、元に戻されたすべてのアイテムが実際にキュー内にある時点で処理スレッド全体を一時停止する方法が必要です (できれば、 while ループ)。

別のミューテックスおよび条件変数と組み合わせた 2 番目の bool 変数 (「一時停止」) について考えましたが、キュー条件でワーカーがシグナルを待機している特別なケースを処理する必要があります。実際には、pthread_cond_wait()呼び出しは両方のミューテックスのロックを解除/ロックする必要があります。

この問題には簡単な解決策があるに違いないと思いますが、それを思い付くことができないようです - あなたの何人かが私を助けてくれることを願っています.

よろしくお願いします。

4

1 に答える 1

4

WaitForMultipleObjects()基本的に、POSIX で WinAPI の呼び出しをエミュレートする必要があります。POSIX には、WinAPI のようにすべてのタイプのイベント/オブジェクトを待機する単一の API はありません。

とを使用pthread_cond_timedwaitclock_gettimeます。多くの実装の詳細については、このペーパーのWaitFor APIを参照してください。

問題を解決できる興味深いコードがいくつかあります(回答に投稿するには多すぎますが、使用可能です)。

PSディスカッションについては、この質問を参照してください: Linux での WaitForSingleObject および WaitForMultipleObjects と同等

于 2012-07-02T08:30:59.773 に答える