Должен ли `.barrier` в параллельной очереди немедленно становиться активным?

Я не уверен, сломалось ли это в бета-версии xcode8 5. Посмотрите на этот код. Как вы думаете, он должен сначала напечатать «A» или «B»?

let q = DispatchQueue(label: "q", attributes: .concurrent)
q.async(flags: .barrier) {
  Thread.sleep(forTimeInterval: 0.25)
  print("A")
}
q.sync {
  print("B")
}

Из-за .barrier я думаю, что он должен блокировать параллельную очередь и печатать «A», «B», но этого не происходит в последней бета-версии xcode.

Ошибка? Непонимание .barrier? Что вы думаете?

обратите внимание: я знаю, что это будет печатать в ожидаемом порядке, если я использую последовательную очередь - это крошечная часть гораздо большей системы, и мне нужно понять это поведение отдельно.


person SimplGy    schedule 13.08.2016    source источник


Ответы (1)


Это была ошибка, исправленная в бета-версии 6.

В бета-версии 5 он не только ведет себя не так, как вы ожидаете, но и предварительное условие .onQueueAsBarrier также не работает. Казалось бы, проблема скрыта в async с опцией .barrier, потому что, если вы выполняете ее через эквивалентный API Objective-C, dispatch_barrier_async, она работает нормально, например:

let q = DispatchQueue(label: "q", attributes: .concurrent)

BarrierExperiment.dispatchBarrierAsync(q) {
    dispatchPrecondition(condition: .onQueueAsBarrier(q))
    Thread.sleep(forTimeInterval: 0.25)
    print("A")
}

q.async() {
    print("B")
}

Где

@interface BarrierExperiment : NSObject

+ (void)dispatchBarrierAsync:(dispatch_queue_t)queue block:(void (^)())block;

@end

@implementation BarrierExperiment

+ (void)dispatchBarrierAsync:(dispatch_queue_t)queue block:(void (^)())block {
    dispatch_barrier_async(queue, block);
}

@end
person Rob    schedule 13.08.2016
comment
Спасибо за сравнение ObjC! Я отправил его команде Swift: bugs.swift.org/browse/SR-2335 Я был впечатлен прозрачностью этой платформы, а не Apple. Может быть, этот код принадлежит Apple? Мне трудно сказать. - person SimplGy; 15.08.2016