在好多网络上的文章里面都有提到将多个串行队列使用dispatch_set_target_queue
设置一个串行队列Target来保持同步执行
dispatch_queue_t q1 = dispatch_queue_create("1", DISPATCH_QUEUE_SERIAL);
dispatch_queue_t q2 = dispatch_queue_create("2", DISPATCH_QUEUE_SERIAL);
dispatch_queue_t q3 = dispatch_queue_create("3", DISPATCH_QUEUE_SERIAL);
dispatch_set_target_queue(q1, q3);
dispatch_set_target_queue(q2, q3);
dispatch_async(q1, ^{
sleep(1);
NSLog(@"1");
});
dispatch_async(q2, ^{
sleep(1);
NSLog(@"2");
});
通过上面代码可以发现,两个串行队列q1,q2本来会同时执行,但是添加了target之后,保持了顺序执行。
但是其实这样做会导致其他问题。
情况1:
dispatch_queue_t q1 = dispatch_queue_create("1", DISPATCH_QUEUE_SERIAL);
dispatch_queue_t q2 = dispatch_queue_create("2", DISPATCH_QUEUE_SERIAL);
dispatch_queue_t q3 = dispatch_queue_create("3", DISPATCH_QUEUE_SERIAL);
dispatch_set_target_queue(q1, q3);
dispatch_set_target_queue(q2, q3);
for (int i = 0; i < 2; i ++) {
dispatch_async(q1, ^{
NSLog(@"123---%@", [NSThread currentThread]);
});
dispatch_async(q2, ^{
NSLog(@"abc---%@", [NSThread currentThread]);
});
}
123---<NSThread: 0x600002e56840>{number = 3, name = (null)}
123---<NSThread: 0x600002e56840>{number = 3, name = (null)}
abc---<NSThread: 0x600002e56840>{number = 3, name = (null)}
abc---<NSThread: 0x600002e56840>{number = 3, name = (null)}
正常情况来说,上面两个任务应该交替执行才对。但是打印结果却是q1任务全部执行完才会执行q2.
所以通过dispatch_set_target_queue
这个方法并不能解决让多个串行队列同步执行的问题。
情况2:
dispatch_queue_t q1 = dispatch_queue_create("1", DISPATCH_QUEUE_SERIAL);
dispatch_queue_t q2 = dispatch_queue_create("2", DISPATCH_QUEUE_SERIAL);
dispatch_queue_t q3 = dispatch_queue_create("3", DISPATCH_QUEUE_SERIAL);
dispatch_set_target_queue(q1, q3);
dispatch_set_target_queue(q2, q3);
for (int i = 0; i < 10; i ++) {
dispatch_async(q1, ^{
NSLog(@"123---%@", [NSThread currentThread]);
});
dispatch_async(q3, ^{
NSLog(@"sss---%@", [NSThread currentThread]);
});
dispatch_async(q2, ^{
NSLog(@"abc---%@", [NSThread currentThread]);
});
}
123---<NSThread: 0x60000029d600>{number = 3, name = (null)}
123---<NSThread: 0x60000029d600>{number = 3, name = (null)}
sss---<NSThread: 0x60000029d600>{number = 3, name = (null)}
abc---<NSThread: 0x60000029d600>{number = 3, name = (null)}
abc---<NSThread: 0x60000029d600>{number = 3, name = (null)}
sss---<NSThread: 0x60000029d600>{number = 3, name = (null)}
根据以上两种情况猜测dispatch_set_target_queue
的执行逻辑:
如果所示,当提交任务到q1时,会将整个q1队列作为q3的任务,同理q2提交任务也一样,而q3是串行队列,所以会将q1队列中所有任务执行完才会执行后续任务。
也就是说当q1任务正在执行时,一直提交任务到q1,那么其他队列的任务都不会执行。