dispatch_suspend 与 dispatch_resume探索

本文探讨了iOS中`dispatch_suspend`和`dispatch_resume`函数的使用,重点在于它们对全局队列和自定义并发队列的影响。实验表明,`dispatch_suspend`在全局队列上无效,但在自定义并发队列上可以阻止新任务的执行。当队列被挂起时,新任务不会执行,直到调用`dispatch_resume`恢复队列。需要注意的是,同步任务可能会导致死锁情况的发生。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

首先探索dispatch_suspend  适用范围截取官方文档一句话

The dispatch queue or dispatch source to suspend. (You cannot suspend other types of dispatch objects.) This parameter cannot be NULL.

意思就是dispatch_suspend(我只支持挂起队列和源对象)不支持其它dispatch objects。

所以dispatch_suspend(挂起对象) “挂起对象”只能是dispatch_queue_t  dispatch_source_t

说到dispatch_queue_t对象 

队列有4种  第一种主队列 主队列如果用dispatch_suspend()  我只能说是在找死,除非你dispatch_suspend()与dispatch_resume()紧挨一起用

第二种是dispatch_get_global_queue队列我们先用一段代码来测试dispatch_suspend()是否对全局队列起作用


-(void)susQueue{

    dispatch_queue_t queueGlobal=dispatch_get_global_queue(0, 0);

    //dispatch_queue_t queueSe=dispatch_queue_create("com.serial", DISPATCH_QUEUE_SERIAL);

    //dispatch_queue_t queueCo=dispatch_queue_create("com.CONCURRENT", DISPATCH_QUEUE_CONCURRENT);

    

    dispatch_async(queueGlobal, ^{

        NSLog(@"1-- %@",[NSThread currentThread]);

    });

    dispatch_async(queueGlobal, ^{

        NSLog(@"2-- %@",[NSThread currentThread]);

    });

    dispatch_async(queueGlobal, ^{

        NSLog(@"3-- %@",[NSThread currentThread]);

    });

    dispatch_async(queueGlobal, ^{

        NSLog(@"4-- %@",[NSThread currentThread]);

    });

    

    dispatch_suspend(queueGlobal);//挂起队列

    dispatch_async(queueGlobal, ^{

        NSLog(@"  111-- %@",[NSThread currentThread]);

    });

    dispatch_sync(queueGlobal, ^{

        NSLog(@"  222-- %@",[NSThread currentThread]);

    });

    

    dispatch_resume(queueGlobal);//恢复队列

    

    dispatch_async(queueGlobal, ^{

        NSLog(@"  33333-- %@",[NSThread currentThread]);

    });

}


结果:

2017-06-14 17:59:49.451 多线程[11553:9534549] 1-- <NSThread: 0x60800007e340>{number = 3, name = (null)}

2017-06-14 17:59:49.451 多线程[11553:9534546] 2-- <NSThread: 0x600000267a00>{number = 4, name = (null)}

2017-06-14 17:59:49.451 多线程[11553:9534547] 3-- <NSThread: 0x60800007e2c0>{number = 5, name = (null)}

2017-06-14 17:59:50.318 多线程[11553:9534427]   222-- <NSThread: 0x608000076cc0>{number = 1, name = main}

2017-06-14 17:59:50.318 多线程[11553:9534547]   33333-- <NSThread: 0x60800007e2c0>{number = 5, name = (null)}

2017-06-14 17:59:50.318 多线程[11553:9534570] 4-- <NSThread: 0x60800007e600>{number = 6, name = (null)}

2017-06-14 17:59:52.021 多线程[11553:9534549]   111-- <NSThread: 0x60800007e340>{number = 3, name = (null)}



我们先对代码进行进行分析

    dispatch_suspend(queueGlobal);//挂起队列

    dispatch_async(queueGlobal, ^{      //任务n

        NSLog(@"  111-- %@",[NSThread currentThread]);

    });

    dispatch_sync(queueGlobal, ^{      //任务n+1

        NSLog(@"  222-- %@",[NSThread currentThread]);

    });

    

    dispatch_resume(queueGlobal);//恢复队列

分析

当遇到dispatch_suspend(queueGlobal)的时候,所有没有加入队列queueGlobal的任务都将暂停 直到遇到    dispatch_resume(queueGlobal);

所以(任务n)和(任务n+1)都不会执行, 但是任务n+1是同步任务不会创建新的线程,

dispatch_suspend(queueGlobal);//挂起队列
异步创建新线程   (开辟新的线程加入任务)
同步在主线程运行(会把自己的任务加在后边)
dispatch_resume(queueGlobal)
     全局队列任务这种情况就造成了死锁  为什么呢? 首页对于异步是肯定不会有问题,但是问题出在同步任务上,

dispatch_sync(queueGlobal, ^{      //任务n+1

        NSLog(@"  222-- %@",[NSThread currentThread]);

    });

    

    dispatch_resume(queueGlobal);//恢复队列

看这两句代码  同步任务代码块会把任务加入全局队列中,但是现在队列中,(此时这个同步任务是在dispatch_resume(queueGlobal)任务后便

这就发生了矛盾 同步任务走完我才能走dispatch_resume(queueGlobal),但是dispatch_resume(queueGlobal)没有走 我的队列都是挂起所以同步任务也无法走,现在就造成了相互等待。

所以结果应该只有

只有1 2 3 4

 所以dispatch_resume对全局队列不起作用


第三种

dispatch_queue_create("com.CONCURRENT", DISPATCH_QUEUE_CONCURRENT);手动创建并发队列

相同代码

结果

2017-06-14 18:35:36.628 多线程[11935:9550718] 1-- <NSThread: 0x608000077900>{number = 3, name = (null)}

2017-06-14 18:35:36.628 多线程[11935:9550570] 4-- <NSThread: 0x600000071a40>{number = 1, name = main}

2017-06-14 18:35:36.628 多线程[11935:9550717] 2-- <NSThread: 0x608000077a00>{number = 4, name = (null)}

2017-06-14 18:35:36.628 多线程[11935:9550720] 3-- <NSThread: 0x60000007c580>{number = 5, name = (null)}


改变代码 将同步任务去掉

    //dispatch_queue_t queueGlobal=dispatch_get_global_queue(0, 0);//刮起了没有作用

    //dispatch_queue_t queueSe=dispatch_queue_create("com.serial", DISPATCH_QUEUE_SERIAL);

    dispatch_queue_t queueCo=dispatch_queue_create("com.CONCURRENT", DISPATCH_QUEUE_CONCURRENT);

    

    dispatch_async(queueCo, ^{

        NSLog(@"1-- %@",[NSThread currentThread]);

    });

    dispatch_async(queueCo, ^{

        NSLog(@"2-- %@",[NSThread currentThread]);

    });

    dispatch_async(queueCo, ^{

        NSLog(@"3-- %@",[NSThread currentThread]);

    });

    dispatch_sync(queueCo, ^{


        //[NSThread sleepForTimeInterval:4.0f];

        NSLog(@"4-- %@",[NSThread currentThread]);

    });

    

    dispatch_suspend(queueCo);//挂起队列

    dispatch_async(queueCo, ^{

        NSLog(@"  111-- %@",[NSThread currentThread]);

    });

//    dispatch_sync(queueCo, ^{

//        NSLog(@"  222-- %@",[NSThread currentThread]);

//    });

    

    dispatch_resume(queueCo);//恢复队列

    

    dispatch_async(queueCo, ^{

        NSLog(@"  33333-- %@",[NSThread currentThread]);

    });


结果:

2017-06-14 18:36:45.586 多线程[11971:9551791] 2-- <NSThread: 0x600000263b80>{number = 4, name = (null)}

2017-06-14 18:36:45.586 多线程[11971:9551723] 4-- <NSThread: 0x608000075f80>{number = 1, name = main}

2017-06-14 18:36:45.586 多线程[11971:9551776] 3-- <NSThread: 0x60800007c980>{number = 5, name = (null)}

2017-06-14 18:36:45.586 多线程[11971:9551773] 1-- <NSThread: 0x60800007c800>{number = 3, name = (null)}

2017-06-14 18:36:49.506 多线程[11971:9551791]   33333-- <NSThread: 0x600000263b80>{number = 4, name = (null)}

2017-06-14 18:36:49.506 多线程[11971:9551773]   111-- <NSThread: 0x60800007c800>{number = 3, name = (null)}





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值