我们什么时候应该使用信号量、调度组和操作队列?



什么时候我们应该使用信号量、调度组和操作队列?

我的理解是:

使用信号量 :当多个线程想要访问共享资源时。

使用调度组:如果需要,您应该在所有线程(添加到调度组(完成执行后收到通知。

使用操作队列:当您希望操作 C 应在 A 和 B 完成其执行后启动时。所以 A 和 B 对 C 有依赖关系。

我的理解是否正确?

我收集的是这三种技术管理工作单元之间依赖关系的能力。最重要的是,信号量是一个低级工具,调度组代表更高级别的抽象,操作队列更高级。

几点观察:

  • 作为一般规则,信号量是一种低级工具,应谨慎使用,因为它们很容易被滥用(例如,容易意外导致死锁,容易阻塞主线程,即使使用得当,它们也会不必要地阻塞效率低下的线程等(。几乎总是有更好、更高级别的工具。

    例如,在进行同步时,锁和 GCD 队列通常不仅提供更高级别的接口,而且效率也更高。

  • 调度组是一个级别稍高的工具,也是在完成一系列 GCD 调度代码块时通知您的好方法。因此,如果您已经在使用 GCD,那么调度组是一个合乎逻辑的解决方案。

    请注意,我建议避免使用wait函数(无论是信号量还是调度组再现(。请改用调度组notify方法。使用notify,可以降低死锁风险,避免不必要地占用线程,避免阻塞主线程的风险等。调度组的wait功能只会重新引入一些相同的潜在信号量问题。但是使用notify时很难出错。

  • 操作队列是一个更高级别的工具。是的,您可以按照概述的方式管理依赖项,但您也可以执行更通用的"按顺序运行一系列异步操作"或"运行一系列异步操作,但一次不超过x个操作"。这是管理一系列异步任务的好方法。

    但操作不仅仅是管理一系列异步工作单元的一种方式。另一个好处是,它提供了一个已建立的框架,将工作单元包装在一个离散的对象中。这可以帮助我们在代码中更好地实现职责分离。因此,您可以为网络操作排队,为图像处理操作排队等,并避免出现这种情况,例如,我们将所有这些代码埋在视图控制器中(lol(。

因此,作为一种严重的过度简化,我建议:

  • 完全避免信号量;
  • 如果您希望在完成
  • 一堆已调度的代码块时收到通知,请使用具有notify模式的调度组;以及
  • 如果要将复杂的异步代码抽象为不同的对象,或者具有更复杂的异步任务依赖项/并发方案,请考虑操作队列。

综上所述,如今,Swift 并发系统(又名 async-await(消除了上述大多数模式,允许人们编写优雅、可读的代码来捕获异步进程。

最新更新