der folgende Code-Snippet Gegeben:dispatch_barrier_sync Deadlocks immer
#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 dispatch_barrier
verwenden, 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, aber ich möchte asynchrones Verhalten vermeiden, weil diese Implementierung nicht-trivial ist. Ich versuche zu verstehen, warum die write
Methode Deadlocking ist. Entsprechend der GCD-Dokumentation:
Wenn der Barriereblock die Front einer privaten gleichzeitigen -Warteschlange erreicht, wird er nicht sofort ausgeführt. Stattdessen wartet die Warteschlange, bis ihre aktuell ausgeführten Blöcke die Ausführung beenden. An diesem Punkt führt die Warteschlange den Sperrblock selbst aus. Alle Blöcke, die nach dem Barriereblock übergeben werden, werden erst ausgeführt, wenn der Barriereblock abgeschlossen ist.
Ich bin verwirrt, was mit "derzeit ausgeführten Blöcken" gemeint ist.
Meine Interpretation ist dieses Szenario, in dem ein Haufen liest (x) vorgelegt bekommen, dann eine Schreib (y), dann mehr liest (z):
- (x) führt
- (y) bis wartet (x)
- (y) Blöcke (z) von der Ausführung
- (x) vervollständigt
- (y) ausführt
- (y) durchgeführt werden, vervollständigt
- (z) führt
- (z)
Ich habe das Sample nicht getestet, aber nachdem ich es betrachtet habe, sollte es _not_ Deadlock nicht sein, IMHO. – CouchDeveloper