iOS 多线程学习笔记 —— dispatch_async在serial queue中的异常

来源:互联网 发布:用邮箱怎么注册淘宝账号 编辑:程序博客网 时间:2024/05/29 08:55

以下是学习了别人的文档后,对自己不太理解的知识点的一点总结。

论点:

同步和异步只需要抓住提交任务后是否是立即返回:同步提交任务到队列后不是立即返回(它要留下来执行任务),异步提交任务到队列后立即返回

串行和并行队列则决定在一个队列中,同一时刻这个队列中是一个线程在执行任务,还是多个线程同时执行任务

注意:

队列之间执行任务并不会相互影响(apple documents: Independent serial queues are processed concurrently with respect to each other.)


以下是简单的一点论证:

知识点:

dispatch_sync(同步)和dispatch_async(异步)的区别——是否立即返回

dispatch_sync:

提交任务到队列后,不是立即返回,而是等到block块中的任务执行完后返回

dispatch_async:

提交任务到队列后,立即返回。(apple documents:Calls to this function always return immediately after the block has been submitted and never wait for the block to be invoked  也就是说dispatch_async只管提交任务,提交任务给队列后,就马上返回到了主线程中。那么执行任务的事就交给了队列。也就可以理解为什么多个队列之间是相互独立的了)

dispatch_async参数(什么队列,任务是什么)

第一个参数:表示将block中的任务加到什么队列中执行

Serial Queue:串行队列

同一时刻,只能执行该队列中的一个任务,不管有几个线程。

Concurrent Queue:并行队列

同一时刻,可以执行该队列中的多个任务

第二个参数:在block中实现想要做的事

补充知识:

block中的代码(block的实现部分)执行特点:

程序并不是遇到block的实现部分就立刻进入block块中执行里面的代码,而是在程序的其他地方(在这里就是apple官方事先写在了某个方法中,专业点叫回调)调用这个block时才执行(block和函数指针一样,block的实现部分得在调用block之前,否则调用也没有意义)


问题实例:

一方法中{

dispatch_async(一个serial串行队列 ,block块{

循环打印 “-”

//注意:这里面的代码是由serial串行队列中的线程来执行的

});

dispatch_async(另一个serial串行队列 ,block块{

循环打印 “+”

//注意:这里面的代码是由另一个serial串行队列中的线程来执行的

});

循环打印 *

//注意:这里的代码是在主线程中的,而主线程没有在serial队列中

}


特别注意:

主线程并没有在serial队列中,而是在主队列中,也就是说存在三个队列,主队列(dispatch_get_main_queue)和两个serial queu队列,那同一时刻程序就会至少执行三个任务:一个是主队列中的,两个serial 队列各执行一个。


问题结果:

程序会穿插打印*、- 和+号,也就是说:虽然我们用的是serial串行队列(一次只能执行一个任务),但是程序却同时执行了多个任务(因为程序并不是将*或者+中的一个完全打印完后再打印另一个,而是穿插打印)。也就说明了队列之间是执行任务是互不影响的


问题结论:

同步和异步只是相对同一个队列来说的,决定这个队列中同一时刻有几个线程在执行任务;

如果有两个或者多个队列,即使都是串行队列,同一时刻,每个队列会独立的执行各自队列中的任务,也就是说,程序在同一时刻会执行多个任务。

0 0