进一步理解GCD

之前转了一篇GCD的文章–iOS中的GCD,近日重新理解了一下GCD。
iOS中实现并行的方式有三种:操作队列(Operation Queue),调度队列(Dispatch Queue)和线程。
注意:

  1. Swift将GCD进行了对象化。我们可以使用DispatchQueue和DispatchGroup的实例方法操作GCD,更符合面向对象的思想。
  2. 文中代码在Swift4中运行良好。
  3. GCD(调度队列)中的核心元素有:队列、任务、调度源等等。

队列(dispatch_queue_t)

typedef NSObject<OS_dispatch_queue> *dispatch_queue_t;

OS_dispatch_queue的定义并没有公开,猜测其中包括了对线程的相关操作。
调度队列按照先进先出的的顺序触发提交到自己的block。
- 串行队列:同时只能执行一个block。
- 并行队列:可同时触发多个block。
三种队列:
- 主队列
- 私有队列
- 全局并发队列

向队列添加任务

  • dispatch_async:异步的向队列中添加任务,不知任务何时开始执行。
  • dispatch_async_f:第二个参数是队列的上下文指针:unsafeBitCast(0, UnsafeMutablePointer.self)
  • dispatch_sync:同步的向队列中添加任务,需要等待任务完成后才能向下执行。
  • dispatch_sync_f
死锁:block等main执行完,main等block执行完
func testDeadLock() {
        let q = DispatchQueue.main
        print("1")
        q.sync {
            print("2")
        }
        print("3")
    }

不死锁:main已释放
func testDeadLock1() {
        let q = DispatchQueue.main
        let gq = DispatchQueue.global()
        gq.async {
            print("1")
            q.sync {
                print("2")
            }
            print("3")
        }
    }

在队列中循环任务(swift3.2中已被废弃)

  • dispatch_apply:
  • dispatch_apply_f:swift3.2中已被废弃

暂定和重启任务(swift3.2中已被废弃)

  • dispatch_suspend:暂停执行队列中的下一个任务。
  • dispatch_resume:继续执行。

任务分组

  • dispatch_group_async:将任务分为一组
  • dispatch_group_wait:某组任务完成后执行下面的操作
    未分组:

    func testGroup() {
        var count = 0
        let concurrentQueue = DispatchQueue.global()
        concurrentQueue.async() {
            print("Task1 in dispatchGroup. Current thread is \(Thread.current)")
            sleep(2)
            count += 1
        }
    
        concurrentQueue.async() {
            print("Task2 in dispatchGroup. Current thread is \(Thread.current)")
            sleep(3)
            count += 1
        }
    
        concurrentQueue.async() {
            print("Task3 in dispatchGroup. Current thread is \(Thread.current)")
            sleep(1)
            count += 1
        }
        print("I expect the count is 3, and the factual count is \(count)")
    }

    执行结果:

I expect the count is 3, and the factual count is 0
Task2 in dispatchGroup. Current thread is <NSThread: 0x604000276d80>{number = 3, name = (null)}
Task1 in dispatchGroup. Current thread is <NSThread: 0x604000276dc0>{number = 5, name = (null)}
Task3 in dispatchGroup. Current thread is <NSThread: 0x60000046dd00>{number = 4, name = (null)}

分组:

var count = 0
        let concurrentQueue = DispatchQueue.global()
        let dispatchGroup = DispatchGroup()
        concurrentQueue.async(group: dispatchGroup) {
            print("Task1 in dispatchGroup. Current thread is \(Thread.current)")
            sleep(2)
            count += 1
        }
        concurrentQueue.async(group: dispatchGroup) {
            print("Task2 in dispatchGroup. Current thread is \(Thread.current)")
            sleep(3)
            count += 1
        }
        concurrentQueue.async(group: dispatchGroup) {
            print("Task3 in dispatchGroup. Current thread is \(Thread.current)")
            sleep(1)
            count += 1
        }
        _ = dispatchGroup.wait(timeout: DispatchTime.distantFuture)
        print("I expect the count is 3, and the factual count is \(count)")

执行结果:

Task1 in dispatchGroup. Current thread is <NSThread: 0x604000471a80>{number = 4, name = (null)}
Task2 in dispatchGroup. Current thread is <NSThread: 0x60000027ebc0>{number = 3, name = (null)}
Task3 in dispatchGroup. Current thread is <NSThread: 0x604000471c00>{number = 5, name = (null)}
I expect the count is 3, and the factual count is 3

任务

调度源(Dispatch Source)

在Swift4(3.2?)已被废弃。

参考:
1,iOS并发编程指南:Dispatch Queue任务执行与Dispatch Source
2,Apple Doc: Dispatch Queue

猜你喜欢

转载自blog.csdn.net/dangyalingengjia/article/details/79409120