swift中的gcd使用大法

Posted by 共田君的博客 on June 26, 2017

swift中的GCD

之前写过一篇文章介绍object-c中的多线程,各种拼凑其实不是很深入,只能当做cookbook来用,然后本次swift是实践的一个结果,每写的一句代码都是自己的,和理解的,如果不理解会用通俗直白语言重复理解,或查阅其他资料整理后直至理解才写出来的。

GCD中OC与swift更新对照表

英文不好的可以翻译看一下翻译

dispatch 译: 分发,分派,任务分发

object-c swift 翻译解释
dispatch_ object_t DispatchObject DispatchQueue,DispatchGroup,和DispatchSource的基类含有挂起继续操作
dispatch_ queue_t DispatchQueue 队列
dispatch_ group_t DispatchGroup 队列组
dispatch_ data_t DispatchData 分发数据,只存在内存中
dispatch_ io_t DispatchIO 操作文件的一个通道(基于流和随机存储的描述符)
dispatch_ semaphore_t DispatchSemaphore 分发 信号
dispatch_ source_t DispatchSource 分发 源
dispatch_ time_t DispatchTime, DispatchWalltime 单个分派任务
C Swift
dispatch_ fd_t Int32
dispatch_ block_t () -> ()
dispatch_ queue_ attr_t DispatchQueueAttributes

看一下OC下多线程思维导图 思维导图

多线程的实现的四种方式

  • pthred
  • NSthread
  • GCD
  • NSOperation

具体介绍查看 http://www.jianshu.com/p/b91b42235285

1. GCD写法

2. 全局队列和主队列获取

3. 添加任务到队列,同步、异步

4. 暂停或继续队列

//MARK: 暂停或执行队列
func pauseorrsume() -> () {
    
//        DispatchQueue.init(label: "concurrentqueue1")
    
    //concurrent 并发线程
    //默认同步线程
//        let queue:DispatchQueue = DispatchQueue(label: "processQueueName")
    
    let queue:DispatchQueue = DispatchQueue(label: "processQueueName", attributes: .concurrent)
    
    queue.async {
        for idx in 1..<5
        {
            sleep(1)
            print("⚪GM\t A:\(idx)")
        }
    }
    
    queue.async {
        for idx in 1..<5
        {
            sleep(1)
            print("🔴GM\t B:\(idx)")
        }
    }
     let time = DispatchTime.now() + .seconds(2)
    DispatchQueue.main.asyncAfter(deadline: time) {
        queue.suspend()
        print("暂停")
    }
    
    //暂停之后加入的任务
    let time3 =  DispatchTime.now() + .seconds(6)
    DispatchQueue.main.asyncAfter(deadline: time3) {
        queue.async {
            for idx in 1..<5
            {
                sleep(1)
                print("🔵GM\t F:\(idx)")
            }
        }
    }
    
    
    let time2 =  DispatchTime.now() + .seconds(15)
    DispatchQueue.main.asyncAfter(deadline: time2) {
        queue.resume()
        print("继续")
        queue.async {
            for idx in 1..<5
            {
                sleep(1)
                print("🔶GM\t E:\(idx)")
            }
        }
        
    }
    //异步任务
    queue.async {
        for idx in 1..<5
        {
            sleep(1)
            print("🔷GM\t C:\(idx)")
        }
    }
    
    
}

5. 一次性执行(单例)

没有dispatch_once之类的代码,请使用swift方式”高级”用法,

static let shareInstance:AClass

6. 线程组,任务队列,与完成通知


func queuegroup() -> () {
    
    let workItem:DispatchWorkItem = DispatchWorkItem.init {
        for idx in 1..<10
        {
            print("🔴GM\t A:\(idx)")
            sleep(1)
        }
    }
    
    let workItem2:DispatchWorkItem = DispatchWorkItem.init {
        for idx in 1..<5
        {
            print("🔵GM\t B:\(idx)")
            sleep(1)
        }
    }
    
    let workItem3:DispatchWorkItem = DispatchWorkItem.init {
        for idx in 1..<20
        {
            print("⚪GM\t B:\(idx)")
//                usleep(500)
            sleep(1)
        }
    }
    
    let queue:DispatchQueue = DispatchQueue(label: "processQueueName", attributes: .concurrent)
    
//        let queue:DispatchQueue = DispatchQueue(label: "workitemqueue", qos: .default)
    //attributes: .concurrent,target: nil
    let group:DispatchGroup = DispatchGroup.init();
    
    
    workItem2.notify(queue: queue) {
        print("任务二完成")
    }
    
    workItem.notify(queue: queue) {
        print("任务一完成")
    }
    
    workItem3.notify(queue: queue) {
        print("任务三完成")
    }
    
    queue.async(group: group, execute: workItem)
    
    queue.async(group: group, execute: workItem2)
    
    queue.async(group: group, execute: workItem3)
    
    
    group.notify(queue: queue) {
        print("任务全部完成")
    }
    
}
    

7. 迭代

8. DispatchSemaphore信号量(临界区)

一句话解释:狭路相逢排队过

这是解决临界区的死锁解锁一种方式,换句话是可以实现死锁和解锁,总共就三个阶段,如下:

  • 设置临界区 DispatchSemaphore(value: 1)
  • 申请使用临界区(开始等待) semaphore.wait()
  • 释放临界区 semaphore.signal()
  //MARK:临界区,狭路相逢排队过
    func signalsampore() -> () {  
        let higherPriority = DispatchQueue.global(qos: .userInitiated)
        let lowerPriority = DispatchQueue.global(qos: .utility)
        
        let semaphore = DispatchSemaphore(value: 1)
        
        func asyncPrint(queue: DispatchQueue, symbol: String) {
            queue.async {
                print("\(symbol) waiting")
                semaphore.wait()  // requesting the resource
               
                //临界区开始 一次只能由一个线程执行这里
                for i in 0...10 {
                    sleep(1)
                    print(symbol, i)
                }
                 print("\(symbol) signal")
                //临界区结束
                semaphore.signal() // releasing the resource
            }
        }
        
        asyncPrint(queue: higherPriority, symbol: "🔴")
        asyncPrint(queue: lowerPriority, symbol: "🔵")
}

推荐博客