今天我尝试了以下代码:
- (void)suspendTest {
dispatch_queue_attr_t attr = dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_CONCURRENT, QOS_CLASS_BACKGROUND, 0);
dispatch_queue_t suspendableQueue = dispatch_queue_create("test", attr);
for (int i = 0; i <= 10000; i++) {
dispatch_async(suspendableQueue, ^{
NSLog(@"%d", i);
});
if (i == 5000) {
dispatch_suspend(suspendableQueue);
}
}
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(6 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
NSLog(@"Show must go on!");
dispatch_resume(suspendableQueue);
});
}
代码开始了10001个任务,但应该在执行了一半的时候暂停队列以便于在6秒后恢复运行新任务。这段代码能够按预期运行 - 5000个任务被执行,然后队列停止,6秒后它会恢复运行。 但是,如果我使用一个串行队列而不是并发队列,它的行为对我来说并不明确。
dispatch_queue_attr_t attr = dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_SERIAL, QOS_CLASS_BACKGROUND, 0);
在这种情况下,有一些任务在挂起之前得以执行,但通常这个数量非常接近于零(在任何任务之前挂起)。 问题是 - 为什么串行队列和并发队列的挂起方式不同,如何正确地挂起串行队列?
if (i == 5000) {
行在for
循环之后。 - rmaddyQOS_CLASS_BACKGROUND
时。所以你不是在说串行队列从未启动吗?既然没有规则,为什么会感到惊讶呢?而且尤其是因为你正在占用主队列,这可能会使后台队列更不愿意启动?毕竟,实际的线程管理不由我们决定;这就是GCD的重点。 - matt