dispatch_barrier_sync immer Deadlocks

Gab das folgende Code-Snippet:

#import <XCTest/XCTest.h>

@interface DispatchTests : XCTestCase {
    dispatch_queue_t _workQueue;
    dispatch_queue_t _readWriteQueue;
    int _value;
}
-(void)read;
-(void)write;
@end

@implementation DispatchTests

-(void)testDispatch {
    _workQueue = dispatch_queue_create("com.work", DISPATCH_QUEUE_CONCURRENT);
    _readWriteQueue = dispatch_queue_create("com.readwrite", DISPATCH_QUEUE_CONCURRENT);
    _value = 0;
    for(int i = 0; i < 100; i++) {
        dispatch_async(_workQueue, ^{
            if(arc4random() % 4 == 0) {
                [self write];
            } else {
                [self read];
            }
        });
    }
    XCTestExpectation* expectation = [self expectationWithDescription:@"dude"];
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        [expectation fulfill];
    });

    [self waitForExpectationsWithTimeout:6.0 handler:nil];
}

-(void)read {
    dispatch_sync(_readWriteQueue, ^{
        NSLog(@"read:%d", _value);
    });
}

-(void)write {
    dispatch_barrier_sync(_readWriteQueue, ^{
        _value++;
        NSLog(@"write:%d", _value);
    });
}

@end

Der Zweck dieses Tests ist zu sehen, ob ich ein @ verwenden kadispatch_barrier, um eine Lese- / Schreibsperre zu verwalten. In diesem Test sind sowohl der Leser als auch der Schreiber synchron. Der Test scheint gut zu funktionieren, wenn ich die Barriere asynchron mache, ich möchte jedoch asynchrones Verhalten vermeiden, da diese Implementierung nicht trivial ist.

Ich versuche zu verstehen, warum diewrite -Methode blockiert. Laut den GCD-Dokumenten:

Wenn der Barrier-Block die erste Stelle einer privaten Warteschlange erreicht, wird er nicht sofort ausgeführt. Stattdessen wartet die Warteschlange, bis die aktuell ausgeführten Blöcke die Ausführung beendet haben. Zu diesem Zeitpunkt führt die Warteschlange den Barriereblock von selbst aus. Nach dem Sperrblock gesendete Blöcke werden erst ausgeführt, wenn der Sperrblock abgeschlossen ist.

Ich bin verwirrt von dem, was unter "derzeitige Ausführung von Blöcken" zu verstehen ist.

Meine Interpretation ist dieses Szenario, in dem ein paar Lesevorgänge (x) gesendet werden, dann ein Schreibvorgang (y) und dann weitere Lesevorgänge (z):

(x) führt @ a (y) wartet bis (x) fertig sind (y) blockiert (z) die Ausführung von (x) vervollständigt (y) führt @ a (y) vervollständigt (z) führt @ a (z) vervollständigt

Antworten auf die Frage(2)

Ihre Antwort auf die Frage