Evg*_*ban 6 multithreading objective-c ios
我正在学习GCD机制,我有几个问题.如果你纠正我,如果我的材料有问题,我将不胜感激.
1.问题)据我所知,GCD有4个不同优先级的全局并发队列.例如,当我们写作时DISPATCH_QUEUE_PRIORITY_HIGH,我们得到一个这样的队列.队列不是空的,一些Apple系统进程在它们上面运行.因此,当我们在某个队列中添加代码块时,例如,当n是随机整数时,它可以是一行中的n个数字任务.
现在,当我们添加代码块时,就像
dispatch_sync(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
// Heavy calculations
});
Run Code Online (Sandbox Code Playgroud)
在viewDidLoad,所有UI组件将被阻止,直到:
我对吗?我知道,我们应该dispatch_async在这里使用,我只是想知道事情是如何运作的.
2.问题)据我所知,所有全局队列都是并发队列,这意味着它可以通过上下文切换或并行来管理任务.但是,当我们通过dispatch_sync到达那个队列时,我们被迫等待,所有的工作都将完成.在这种情况下唯一不同于串行队列的是操作顺序.例如,如果串行队列有任务1,任务2,任务3和任务4,它将严格按顺序执行此操作,但并发队列可以更改它的顺序,以首先完成轻量级操作.
所以,我的问题是,我们为什么要这样做dispatch_sync?根据我的理解,主线程将被阻止,直到dispach_sync代码块完成.
Ken*_*ses 13
GCD有4个具有不同优先级的全局并发队列.例如,当我们写作时
DISPATCH_QUEUE_PRIORITY_HIGH,我们得到一个这样的队列.队列不是空的,一些Apple系统进程在它们上面运行.
在任何给定时间,队列可能是空的或可能不是.没有办法知道.是的,框架可能会像代码一样向这些队列添加内容.
但是,队列不会运行.队列是一种数据结构.它按顺序执行任务.GCD根据需要管理一组工作线程,创建新线程或让它们退出.这些工作线程将任务从队列中取出并执行它们.
当我们添加代码块时,比如
Run Code Online (Sandbox Code Playgroud)dispatch_sync(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{ // Heavy calculations });在
viewDidLoad,所有UI组件都将被阻止,直到:1 - Apple系统任务将完成(因为我们在该队列中最后添加我们的任务,并应该等到其他系统任务完成)2 - 直到我们的代码完成.
顾名思义,dispatch_sync()是同步的.这意味着它在完成它被要求做的工作(你通过的块)之前不会返回.是否必须等待队列中的任何其他任务取决于可用的系统资源.正如您所指出的那样,队列是并发的,因此可以将任务拉出并同时运行.如果有足够的可用CPU核心,GCD可以启动足够的工作线程来同时运行队列上的所有任务.因此,您的任务不必等待其他任务完成,它只需等待这些任务已经启动(从队列的头部弹出)并且有可用的备用工作线程.
如果所有系统资源(如CPU核心)都忙,则只需等待其他任务完成.
据我所知,所有全局队列都是并发队列,这意味着它可以通过上下文切换或并行来管理任务.但是,当我们通过dispatch_sync到达那个队列时,我们被迫等待,所有的工作都将完成.
不,这是错的,正如我上面解释的那样.您知道在dispatch_sync()返回之前必须完成的唯一事情是您使用它提交的一项任务.除非所有CPU核心都忙,否则它不必等待该队列上的任何其他任务.
在这种情况下唯一不同于串行队列的是操作顺序.例如,如果串行队列有任务1,任务2,任务3和任务4,它将严格按顺序执行此操作,但并发队列可以更改它的顺序,以首先完成轻量级操作.
不会.并发队列严格按顺序启动操作,就像串行队列一样.只是串行队列才会启动另一个操作,直到当前的一个操作完成.全局并发队列将允许其所有操作同时启动和运行,直至可用资源.队列无法知道操作是否轻量级.
所以,我的问题是,我们为什么要做dispatch_sync?根据我的理解,主线程将被阻止,直到
dispach_sync代码块完成.
并发和同步行为是两个独立的概念.同步与异步决定了调用者的行为.它确定在完成工作之前是否允许调用者继续.
并发与串行确定如何运行提交的任务.并发队列允许任务彼此同时运行.串行队列只允许其中一个任务一次运行.
dispatch_sync()从主线程调用是有意义的,但你必须要小心.例如,当使用串行队列来同步对多个线程共享的数据结构的访问时,可能是必要的.一般规则是您需要避免长时间阻塞主线程.如果您有充分的理由相信它会在很短的时间内被用户无法察觉,那么可以阻止它.
你绝对不想dispatch_sync()在主线程中使用"重计算".
通常,您可以dispatch_sync()在需要完成任务之前使用,然后才能继续.通常,您可以重构代码,而不是使用dispatch_async()后续代码作为延续步骤(或完成处理程序).但你不能总是那样做.
| 归档时间: |
|
| 查看次数: |
1573 次 |
| 最近记录: |