【问题标题】:Concurrent insertion of blocks into concurrent queue将块并发插入并发队列
【发布时间】:2019-12-05 14:00:57
【问题描述】:
我想将块 A、B、C 添加到全局并发队列中。
紧接着我想在同一个队列中添加障碍。
我希望 A、B、C 都以某种顺序被调用,但是当所有块终止时,将调用屏障。
我如何保证不会在这个序列的中间插入额外的块?例如,如果在其他地方我将块 X 部署在同一个队列上,我不希望它在屏障之前执行。
相同的解决方案能否在 MacOS 和 iOS 上都可用?
【问题讨论】:
标签:
ios
objective-c
macos
cocoa
grand-central-dispatch
【解决方案1】:
障碍不适用于全局队列。创建您自己的自定义并发队列。正如dispatch_barrier_async documentation 所说:
您指定的队列应该是您使用dispatch_queue_create 函数自己创建的并发队列。如果您传递给此函数的队列是串行队列或全局并发队列之一,则此函数的行为类似于dispatch_async 函数。
那么在屏障之后分派到该队列的任何内容都不会在屏障之后运行。所以分派 A、B 和 C。然后用屏障分派 D。然后调度 X。A、B 和 C 将相对于彼此同时运行,当它们完成时,D 将运行,当 D 完成时,X 将运行。这就是它在 macOS 和 iOS 上的工作原理。只需创建您自己的自定义并发队列。
dispatch_queue_t queue = dispatch_queue_create("com.company.app.queue", DISPATCH_QUEUE_CONCURRENT);
dispatch_async(queue, ^{
NSLog(@"start - A!\n");
sleep(4);
NSLog(@"end - A!\n");
});
dispatch_async(queue, ^{
NSLog(@"start - B!\n");
sleep(2);
NSLog(@"end - B!\n");
});
dispatch_async(queue, ^{
NSLog(@"start - C!\n");
sleep(3);
NSLog(@"end - C!\n");
});
dispatch_barrier_async(queue, ^{
NSLog(@"Barrier - D\n");
});
dispatch_async(queue, ^{
NSLog(@"start - X!\n");
sleep(3);
NSLog(@"end - X!\n");
});