dispatch_barrier_sync sempre entra em conflito
Dado o seguinte trecho de código:
#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
O objetivo deste teste é verificar se posso usar umdispatch_barrier
para gerenciar um bloqueio de leitura / gravação. Neste teste, o leitor e o gravador são síncronos. O teste parece funcionar bem quando eu faço a barreira assíncrona, no entanto, gostaria de evitar um comportamento assíncrono porque essa implementação não é trivial.
Estou tentando entender por que owrite
O método está em conflito. De acordo com os documentos da GCD:
Quando o bloco de barreira atinge a frente de uma fila simultânea privada, ele não é executado imediatamente. Em vez disso, a fila espera até que seus blocos atualmente em execução terminem de ser executados. Nesse ponto, a fila executa o bloco de barreira por si só. Quaisquer blocos enviados após o bloqueio de barreira não serão executados até que o bloqueio de barreira seja concluído.
Estou confuso com o que se entende por "atualmente executando blocos".
Minha interpretação é esse cenário em que várias leituras (x) são enviadas, depois uma gravação (y) e mais leituras (z):
(x) executa(y) aguarda até que (x) seja concluído(y) bloqueia (z) a execução(x) termina(y) executa(y) termina(z) executa(z) termina