队列上的屏障不会影响其目标队列。
这是最容易通过经验证明的。例如:
- (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。所有任务都需要一秒钟。
结果如下。 (我手动突出显示了这些任务编号以使这一点更清楚。)
您可以看到队列 1 上的任务 #5 在排队时立即启动,即使 (a) 它是排队的最后一个任务,并且 (b) 队列 2 对任务 #3 有障碍。不过,第二个队列尊重任务 3 的障碍。
仅供参考,这些是生成points of interest 范围的实用方法:
- (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 所做的那样。