0

私は、2 つのキューが異なるスレッドで実行されるようにしたい状況にあります。理想的には、それらがシリアル キューであることを確認したいと思います。特に、以下の例では、両方のキューが同じスレッドで実行されている場合、doStuff は無期限にビジー待機状態になります。明示的なスレッド化に移行する必要がありますか、それともここで GCD の使用を救うことができますか?

- (void)foo {
    self.responseQueue = dispatch_queue_create("com.blah.response", DISPATCH_QUEUE_SERIAL);

    self.requestQueue = dispatch_queue_create("com.blah.request", DISPATCH_QUEUE_SERIAL);

    dispatch_async(self.requestQueue, ^{
        [self doStuff];
    });
}

- (BOOL)doStuff {
    BOOL __block waiting = YES;

    self.responseBlock = ^{
        waiting = NO;
    };

    [self performRequest];

     while (waiting) {
         // realize could use dispatch_semaphore (busy waiting just to illustrate point).    
         sleep(1);
     }

     [self doStuffRequiringResponseCompletion];

     // I realize it would be sensible to 
     // 1) Not block in the above while loop.
     // 2) Call |doStuffRequiringResponseCompletion| after |receivedResponse|.
     // I don't want to do this.
}

// method called on arbitrary thread
- (void)receivedResponse {
    // stuff

    dispatch_async(self.responseQueue, self.responseBlock);
}

参照: Grand Central Dispatch キューでスリープを使用しない理由はありますか? ?

4

4 に答える 4

1

それらが異なるスレッドで実行されることを保証することはできません。ディスパッチ キューのポイントは、OS がスレッドを管理することです。ただし、特定のスレッドで実行することが本当に本当に必要な、高度に専門化された作業を行っている場合を除き、シリアル ディスパッチ キューのデフォルトの動作はうまく機能するはずです。特定のスレッドを確実にする必要がある場合は、NSThread の使用に戻ります。

于 2013-07-15T23:52:45.460 に答える
0

同期の目的でディスパッチ キューを悪用するべきではないため、このソリューションの使用はお勧めしませんが、これは私が求めていたものです (ただし、これはデッドロックしないことが保証されていません。dispatch_sync ブロックが別のスレッドで実行された場合、デッドロックが発生する可能性があります)。 performSelectorInBackground によってスピンアップされたもの):

- (void)foo {
    self.responseQueue = dispatch_queue_create("com.blah.response", DISPATCH_QUEUE_SERIAL);

    self.requestQueue = dispatch_queue_create("com.blah.request", DISPATCH_QUEUE_SERIAL);

    [self performSelectorInBackground:@selector(dispatchRequest) withObject:nil]
}

- (void)dispatchRequest {
    dispatch_sync(self.requestQueue, ^{
        [self doStuff];
    });
}
于 2013-07-16T01:29:29.820 に答える
0

スレッドをブロックしないようにする必要があります。あなたの例を使用して、応答ブロックで応答を処理した後、別のブロックを com.blah.request でキューに戻して、待っていたことを何でも実行できます。

于 2013-07-16T00:04:58.437 に答える