考虑下面的代码片段:dispatch_barrier_sync总是锁死
#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
这个测试的目的是为了看看我是否可以使用dispatch_barrier
管理的读/写锁。在这个测试中,读写器都是同步的。当我使屏障异步时,测试似乎工作正常,但是我想避免异步行为,因为此实现不重要。
我想了解为什么write
方法是死锁。根据GCD文档:
当阻挡块达到私人并发 队列的前部,它不立即执行。相反,队列一直等到其当前正在执行的块的 完成执行。此时, 队列自行执行障碍块。在屏障块完成之前,任何在 屏障块之后提交的块都不会执行。
我很困惑“当前正在执行的块”的含义。
我的理解是这样的场景,一群读取(X)获得提交,然后写(Y),那么更多的读取(Z):
- (x)的执行
- (Y)等待,直到(X)是从执行完成
- (y)的块(Z)
- (x)的完成
- (Y)执行
- (y)的完成
- (Z)执行
- (Z)完成
我没有测试过该示例,但看了它之后,它应该_not_死锁,恕我直言。 – CouchDeveloper