Барьер в очереди не влияет на целевую очередь.
Это легче всего продемонстрировать опытным путем.Например:
- (void)experiment {
dispatch_queue_t queue1 = dispatch_queue_create("1", DISPATCH_QUEUE_CONCURRENT);
dispatch_queue_t queue2 = dispatch_queue_create_with_target("2", DISPATCH_QUEUE_CONCURRENT, queue1);
dispatch_async(queue1, ^{
[self taskOnQueue:1 taskNumber:1 color:1];
});
dispatch_async(queue2, ^{
[self taskOnQueue:2 taskNumber:2 color:0];
});
dispatch_barrier_async(queue2, ^{
[self taskOnQueue:2 taskNumber:3 color:0];
});
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
dispatch_async(queue2, ^{
[self taskOnQueue:2 taskNumber:4 color:0];
});
dispatch_async(queue1, ^{
[self taskOnQueue:1 taskNumber:5 color:1];
});
});
}
Задачи 1-3 отправляются немедленно, а задачи 4 и 5 отправляются через 0,5 секунды.Задача 3 использует барьер.Задачи 1 и 5 находятся на queue1
, а задачи 2-4 - на queue2
.Все задачи занимают одну секунду каждая.
Это приводит к следующему.(Я вручную выделил эти номера задач, чтобы сделать это более понятным.)
Вы можете видеть, что задача № 5 в очереди 1 запускается, как только онав очереди, даже если (а) это была последняя задача, поставленная в очередь, и (б) очередь 2 имеет барьер для задачи № 3.Однако вторая очередь учитывает барьер для задачи 3.
К вашему сведению, это служебные методы, которые генерируют эти точки интереса диапазоны:
- (void)taskOnQueue:(uint32_t)code taskNumber:(uint32_t)arg1 color:(uint32_t)arg4 {
[self pointOfInterest:code arg1:arg1 color:arg4 block:^{
[NSThread sleepForTimeInterval:1];
}];
}
- (void)pointOfInterest:(uint32_t)code arg1:(uint32_t)arg1 color:(uint32_t)arg4 block:(void (^)(void))block {
kdebug_signpost_start(code, arg1, 0, 0, arg4);
block();
kdebug_signpost_end(code, arg1, 0, 0, arg4);
}
Примечание: обратное утверждение - это совершенно другая проблема.Очереди будут затронуты, если их целевая очередь имеет барьер.Если целевая очередь заблокирована (например, если вы измените задачу 3 на выполнение с барьером в целевой очереди вместо queue1
), то задачи во второй очереди будут ожидать освобождения своей целевой очереди:
- (void)experiment2 {
dispatch_queue_t queue1 = dispatch_queue_create("1", DISPATCH_QUEUE_CONCURRENT);
dispatch_queue_t queue2 = dispatch_queue_create_with_target("2", DISPATCH_QUEUE_CONCURRENT, queue1);
dispatch_async(queue1, ^{
[self taskOnQueue:1 taskNumber:1 color:1];
});
dispatch_async(queue2, ^{
[self taskOnQueue:2 taskNumber:2 color:0];
});
dispatch_barrier_async(queue1, ^{ // changed to queue 1
[self taskOnQueue:1 taskNumber:3 color:1];
});
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
dispatch_async(queue2, ^{
[self taskOnQueue:2 taskNumber:4 color:0];
});
dispatch_async(queue1, ^{
[self taskOnQueue:1 taskNumber:5 color:1];
});
});
}
Это приведет к:
Здесь задача 3 была отправлена с барьером (где находится этот первый Ⓢ указатель)и он не только не запустился, пока задача 1 не была выполнена в целевой очереди, но и задача 4 (работающая во второй очереди) во второй очереди (отправленная там, где находится этот второй указатель) ожидала этого барьера в целевой очереди своей очередиТочно так же, как задача 5.