dispatch_barrier_async如何与目标队列互动?

时间:2018-12-20 16:40:43

标签: ios grand-central-dispatch

创建目标为queue1(queue2 = dispatch_queue_create_with_target(name, attr, queue1))的queue2 ...

如果两个队列是并发的,queue2上的dispatch_barrier_async仅等待queue2为空,还是还要等待目标队列?当两个队列中都有各自的屏障块排队时,queue2的屏障块优先吗?

1 个答案:

答案 0 :(得分:2)

队列上的障碍不会影响其目标队列。

根据经验最容易证明这一点。例如:

- (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,并在0.5秒后分派任务4和5。任务3正在使用障碍。任务1和5在queue1上,任务2-4在queue2上。所有任务各花费一秒钟。

结果如下。 (我手动突出显示了这些任务编号,以使其更加清楚。)

enter image description here

您可以看到,队列(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];
        });
    });
}

这将导致:

enter image description here

在这里,任务3被分派了障碍(第一个Ⓢ路标所在的位置),不仅直到在目标队列上完成任务1之后它才开始,而且任务4(在第二个队列上运行)也没有开始。就像任务5一样,第二个队列(在第二个Ⓢ路标所在的位置调度)也在其队列的目标队列上等待该障碍。