0

次のシナリオがあります。

コードの特定のセクションをすべて通過する複数のワーカー スレッドが実行されており、同時に実行することが許可されています。これらのスレッドには必要ないため、現時点ではこのコードを囲むクリティカル セクションはありません。

メイン スレッドも - 時折 - コードのそのセクションに入りたいと思っていますが、入った場合、他のワーカー スレッドはコードのそのセクションを使用すべきではありません。

単純な解決策: コードのセクションをクリティカル セクションで囲みます。しかし、それはワーカー スレッド間の多くの並列処理を無効にします。これは私の場合は重要です。

より良い解決策はありますか?

4

2 に答える 2

0

RWロックを使用します。RWロックでは、複数のリーダーと1つのライターのみが許可されます。ワーカーはクリティカルセクションの開始時にread-lockを呼び出し、メインスレッドはwrite-lockを呼び出します。

定義上、read-lockを呼び出すと、呼び出しプロセスは書き込みスレッドが終了するのを待ちます。write-lockを呼び出す場合、呼び出しプロセスは読み取りまたは書き込みスレッドが終了するのを待ちます。

POSIXスレッドの使用例:

pthread_rwlock_t lock;
/* worker threads */
void *do_work(void *args) {
    for (int i = 0; i < 100; ++i) {
        pthread_rwlock_rdlock(&lock);
        // do some work...
        pthread_rwlock_unlock(&lock);
        sleep(1);
    }
    pthread_exit(0);
}

/* main thread */
int main(void) {
    pthread_t workers[4];
    pthread_rwlock_init(&lock);
    int i;

    // spawn workers...
    for (i = 0; i < 4; ++i) {
        pthread_create(workers[i]; NULL, do_worker, NULL);
    }
    for (i = 0; i < 100, ++i) {
        pthread_rwlock_wrlock(&lock);
        // do some work...
        pthread_rwlock_unlock(&lock);
        sleep(1);
    }

    return 0;
}
于 2013-02-03T18:33:45.043 に答える
-1

私が理解している限り、ワーカースレッドは非同期で開始されます。したがって、メインスレッドがこのコードセクションを実行する場合は、ワーカースレッドが実行していないことを確認する必要があります。したがって、メインスレッドがそのコードセクションに入る前にすべてのワーカースレッドを停止し、後で再び入ることができるようにする必要があります。
これは、Grand Central Dispatchを使用して行うことができます。ワーカースレッドがディスパッチグループに割り当てられる場合は、https://developer.apple.com/library/mac/#documentation/Performance/Reference/GCD_libdispatch_Ref/Reference/referenceを参照してください。 html
次に、メインスレッドはdispatch_group_waitこのディスパッチグループにメッセージを送信し、すべてのワーカースレッドがこのコードセクションを離れるのを待って実行し、ワーカースレッドを再キューイングできます。

于 2013-02-03T20:40:37.693 に答える