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:
Когда барьерный блок достигает фронта частной параллельной очереди, он не выполняется немедленно. Вместо этого очередь ожидает, пока ее выполняющиеся в данный момент блоки не завершатся. В этот момент очередь выполняет барьерный блок самостоятельно. Любые блоки, представленные после блока барьера, не выполняются, пока блок барьера не завершится.
Я смущен тем, что подразумевается под "выполняемыми в настоящее время блоками".
Моя интерпретация - это сценарий, в котором передается группа reads (x), затем write (y), затем больше reads (z):
(х) выполняет(у) ждет, пока (х) не будет сделано(у) блоки (z) от выполнения(х) завершает(у) выполняет(у) завершает(z) выполняет(z) завершает