多线程

Swift补充- 多线程(DispatchQueue & Dis

2022-07-21  本文已影响0人  看谷秀

目录

  1. DispatchQueue
  2. DispatchWorkItem

1 DispatchQueue 队列 async/ sync

public convenience init(label: String,  // 标识符
qos: DispatchQoS = .unspecified,  // 优先级
attributes: DispatchQueue.Attributes = [], // 指定队列
autoreleaseFrequency: DispatchQueue.AutoreleaseFrequency = .inherit, // 队列释放策略
target: DispatchQueue? = nil ) // 目标队列  

(参数-1) label:String : 队列的标识符,方便在调试工具(如 Instruments, 奔溃日志)中找到对应的信息。

(参数-2) qos: DispatchQoS : 该值确定系统安排任务执行的优先级。
QoS类对要在DispatchQueue上执行的工作进行了分类。 通过指定任务的qos,可以表明任务对应用程序的重要性。
在安排任务时,系统会优先处理服务级别较高的任务。因为高优先级的工作比低优先级的工作执行得更快,资源更多,所以与低优先级的工作相比,通常需要更多的精力。 为您的应用执行的工作准确地指定适当的QoS类可确保您的应用具有响应能力和能源效率。

优先级 background < utility < default < userInitiated < userInteractive

在OC中的定义

typedef uint32_t dispatch_qos_t;
typedef uint32_t dispatch_priority_t;

#define DISPATCH_QOS_UNSPECIFIED        ((dispatch_qos_t)0)
#define DISPATCH_QOS_MAINTENANCE        ((dispatch_qos_t)1)
#define DISPATCH_QOS_BACKGROUND         ((dispatch_qos_t)2)
#define DISPATCH_QOS_UTILITY            ((dispatch_qos_t)3)
#define DISPATCH_QOS_DEFAULT            ((dispatch_qos_t)4)
#define DISPATCH_QOS_USER_INITIATED     ((dispatch_qos_t)5)
#define DISPATCH_QOS_USER_INTERACTIVE   ((dispatch_qos_t)6)
#define DISPATCH_QOS_MIN                DISPATCH_QOS_MAINTENANCE
#define DISPATCH_QOS_MAX                DISPATCH_QOS_USER_INTERACTIVE
#define DISPATCH_QOS_SATURATED          ((dispatch_qos_t)15)

(参数-3) attributes: DispatchQueue.Attributes 与队列关联的属性。 包括并发属性以创建可以同时执行任务的调度队列。 如果省略该属性,则分派队列将串行执行任务。

//激活在非活动状态下创建的队列
@available(iOS 10.0, *)
public func activate()

//可以挂起一个队列,就是把这个线程暂停了,它占着资源,但不运行。
@available(iOS 4.0, *)
public func suspend()
//可以继续挂起的队列,让这个线程继续执行下去。
@available(iOS 4.0, *)
public func resume()

(参数-4) autoreleaseFrequency: DispatchQueue.AutoreleaseFrequency 调度队列自动释放对象的频率。

(参数-1) target: DispatchQueue? 要在其上执行块的目标队列。 如果希望系统提供适合于当前对象的队列,请指定DISPATCH_TARGET_QUEUE_DEFAULT。

//在OC中的定义
void
dispatch_set_target_queue(dispatch_object_t object,
        dispatch_queue_t _Nullable queue);

设置taget的作用 官方文档

let queue1 = DispatchQueue.init(label: "串行队列1")
let queue2 = DispatchQueue.init(label: "并发队列",attributes: .concurrent,target: queue1)
for i in 0..<10 {
    queue2.async { 
        print("queue2 任务\(i)",Thread.current)
    }
}
/*
// 有目标target队列 不分配新队列
queue2 任务0 <NSThread: 0x600003449580>{number = 7, name = (null)}
queue2 任务1 <NSThread: 0x600003449580>{number = 7, name = (null)}
queue2 任务2 <NSThread: 0x600003449580>{number = 7, name = (null)}
queue2 任务3 <NSThread: 0x600003449580>{number = 7, name = (null)}
queue2 任务4 <NSThread: 0x600003449580>{number = 7, name = (null)}
queue2 任务5 <NSThread: 0x600003449580>{number = 7, name = (null)}
queue2 任务6 <NSThread: 0x600003449580>{number = 7, name = (null)}
queue2 任务7 <NSThread: 0x600003449580>{number = 7, name = (null)}
queue2 任务8 <NSThread: 0x600003449580>{number = 7, name = (null)}
queue2 任务9 <NSThread: 0x600003449580>{number = 7, name = (null)}
*/        
let queue1 = DispatchQueue.init(label: "串行队列1")
let queue2 = DispatchQueue.init(label: "并发队列",attributes: .concurrent,target: nil)
for i in 0..<10 {
    queue2.async { 
        print("queue2 任务\(i)",Thread.current)
    }
}
/*
// 没有目标target队列 分配新队列
queue2 任务0 <NSThread: 0x600002c41600>{number = 5, name = (null)}
queue2 任务3 <NSThread: 0x600002c1d040>{number = 6, name = (null)}
queue2 任务2 <NSThread: 0x600002c75bc0>{number = 4, name = (null)}
queue2 任务1 <NSThread: 0x600002c44cc0>{number = 3, name = (null)}
queue2 任务4 <NSThread: 0x600002c18380>{number = 7, name = (null)}
queue2 任务5 <NSThread: 0x600002c10600>{number = 8, name = (null)}
queue2 任务6 <NSThread: 0x600002c1d0c0>{number = 9, name = (null)}
queue2 任务7 <NSThread: 0x600002c14140>{number = 10, name = (null)}
queue2 任务8 <NSThread: 0x600002c187c0>{number = 11, name = (null)}
queue2 任务9 <NSThread: 0x600002c1d140>{number = 12, name = (null)}
*/

设置目标队列时,不要将队列A的目标设置为队列B,又将队列B的目标设置为队列A。

let queue1 = DispatchQueue.init(label: "并发队列1",attributes: .concurrent)
let queue2 = DispatchQueue.init(label: "串行队列1",target: queue1)
let queue3 = DispatchQueue.init(label: "串行队列3",target: queue1)

for i in 0..<10 {
    queue2.async {
        print("queue2 任务\(i)")
    }

    queue3.async {
        print("*******queue3 任务\(i)")
    }
}
//输出
/*
queue2 任务0
*******queue3 任务0
queue2 任务1
queue2 任务2
*******queue3 任务1
queue2 任务3
*******queue3 任务2
queue2 任务4
queue2 任务5
queue2 任务6
queue2 任务7
queue2 任务8
queue2 任务9
*******queue3 任务3
*******queue3 任务4
*******queue3 任务5
*******queue3 任务6
*******queue3 任务7
*******queue3 任务8
*******queue3 任务9
*/

————————————————
原文链接:https://blog.csdn.net/u013756604/article/details/111224217

—————————————————————————————————————————

2 DispatchWorkItem 使用

DispatchWorkItem是封装work的对象,可以监听work完成的通知,并指定和其他DispatchWorkItem之间的依赖关系。

DispatchWorkItem结构

DispatchWorkItem 是一个Class, 含有一个 实例变量表示任务是否被取消

var isCancelled: Bool

同时,你可以调用 DispatchWorkItem 的取消方法

func cancel()
Cancels the current work item asynchronously.

DispatchWorkItem 实践

let work1 = DispatchWorkItem {
    print("Simple Pure Work")
}
DispatchQueue.global().async(execute: work1)
let work1 = DispatchWorkItem {
   print("Simple Pure Work")
}
DispatchQueue.global().sync(execute: work1)
// 异步队列
let work2 = DispatchWorkItem(qos: .background) {
      print("Work background(后台优先级最低\(Thread.current)")
}

let work3 = DispatchWorkItem(qos: .userInteractive) {
     print("Work userInteractive(最高优先级)\(Thread.current)")
}

DispatchQueue.global().async(execute: work2)
DispatchQueue.global().async(execute: work3)
/**
Work userInteractive(最高优先级)<NSThread: 0x600001ee60c0>{number = 5, name = (null)}
Work background(后台优先级最低<NSThread: 0x600001eefb00>{number = 4, name = (null)}
*/
//任务 2
let work2 = DispatchWorkItem(qos: .default, flags: .enforceQoS) {
      print("work2")
}
// 任务 3
let work3 = DispatchWorkItem(qos: .default, flags: .barrier) { // 类似栅栏函数
      Thread.sleep  (forTimeInterval: 3)
      print("work3")
}
// 任务 4
let work4 = DispatchWorkItem(qos: .default) {
      print("work4")
}
// 队列 q
let q = DispatchQueue(label: "concurrent", attributes: .concurrent)
      q.async(execute: work2)
      q.async(execute: work3)
      q.async(execute: work4)
        
/** work2
    work3
    work4*/
//work2执行完毕, 停留3秒, 在执行work4
 /// 强制使用当前work的QoS
let work2 = DispatchWorkItem(qos: .default, flags: .enforceQoS) {
      print("work2\(Thread.current)")
}
/// inheritQoS 继承队列的QoS
let work3 = DispatchWorkItem(qos: .default, flags: .inheritQoS) {
      Thread.sleep(forTimeInterval: 3)
      print("work3\(Thread.current)")
}
/// work执行的时候使用当前的上下文?(具体有点不清晰)
let work4 = DispatchWorkItem(qos: .default, flags: .assignCurrentContext) {
      print("work4\(Thread.current)")
}

let q = DispatchQueue(label: "concurrent", attributes: .concurrent)
      q.async(execute: work2)
      q.async(execute: work3)
      q.async(execute: work4)
/**
work2<NSThread: 0x600002d618c0>{number = 5, name = (null)}
work4<NSThread: 0x600002d61e40>{number = 4, name = (null)}
work3<NSThread: 0x600002d5cd80>{number = 6, name = (null)}*/
let work = DispatchWorkItem {
     print("work start\(Thread.current)")
     Thread.sleep(forTimeInterval: 5)
}
work.notify(queue: .main) {
     print("work done\(Thread.current)")
}
work.notify(queue: .global(), execute: DispatchWorkItem(block: {
     print("work item done\(Thread.current)")
}))
DispatchQueue.global().async(execute: work)
/**
   work start<NSThread: 0x60000222ef00>{number = 6, name = (null)}
   work done<_NSMainThread: 0x6000022bc300>{number = 1, name = main}
   work item done<NSThread: 0x60000222ef00>{number = 6, name = (null)}
*/
// wait()函数 等任务执行完毕, 在往下执行
let queue = DispatchQueue(label: "queue", attributes: .concurrent)
let workItem1 = DispatchWorkItem {
    sleep(3)
    print("workItem")
}
        
let workItem2 = DispatchWorkItem {
    sleep(2)
    print("workItem2")
}
            
    queue.async(execute: workItem1)
    queue.async(execute: workItem2)
    print("before waiting")
    workItem1.wait() // 等待item1任务执行完, 执行后面任务
    workItem2.wait()
    print("after waiting")
     
/* before waiting
   workItem2  
   workItem
   after waiting */

原文链接 https://blog.csdn.net/m0_55782613/article/details/123117539

上一篇下一篇

猜你喜欢

热点阅读