多线程
一、Grand Central Dispatch(GCD )
GCD 是苹果开发的一个多核编程的方法,采用了线程池模式,支持多核处理器
优点:
1、GCD 可用于多核的并行运算;
2、GCD 会自动利用更多的 CPU 内核(比如双核、四核);
3、GCD 会自动管理线程的生命周期(创建线程、调度任务、销毁线程);
可实现的功能:
1、多任务并行执行
2、计时器&延时执行
3、多任务之间依赖执行
队列(FIFO):串行队列 并行队列,存放将要执行的任务。串行队列只有一个线程,所有任务在这一个线程中顺序执行;并行队列可以有多个线程,所有任务可以在不同线程同时执行
执行:异步执行和同步执行,异步执行后需任务无需等待上一个任务执行完毕,可以直接开启其他开启新线程执行;同步执行,等待上一个任务执行完毕后才开始执行;同步/异步决定是否开启新线程,串行/并行决定开启新线程数量。
多线程:并行队列+异步执行,多线程最大并发量可以通过信号量控制
获取队列
// 串行队列的创建方法
dispatch_queue_t queue = dispatch_queue_create("队列名称标识", DISPATCH_QUEUE_SERIAL);
// 并发队列的创建方法
dispatch_queue_t queue = dispatch_queue_create("队列名称标识", DISPATCH_QUEUE_CONCURRENT);
//获取主队列 ->串行队列
dispatch_get_main_queue()
//获取全局队列-> 并行队列
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
添加任务
异步添加任务
dispatch_async(queue, ^{
});
同步添加任务
dispatch_sync(queue, ^{
});
GCD之间的通信:异步添加任务到其他线程
其他方法
栅栏方法:dispatch_barrier_async(queue, ^{ });
同一队列中,等待栅栏函数前的任务完成才会执行栅栏内任务,最后回复继续执行原流程
延时方法:dispatch_after(timer, queue, ^{ });
timer 是dispatch_time_t类型,dispatch_time(计时开始时间, 延迟时间);
只是在时间节点将任务添加到队列中,准备执行,时间上不准确
一次执行:dispatch_once(dispatch_once_t,^{});
保证线程安全,常用来实现单例
迭代方法: dispatch_apply(count, queue, ^(size_t index) { });
异步执行count次数迭代方法,无先后顺序,
队列组 dispatch_group
创建队列组: dispatch_group_create();
添加任务标识:dispatch_group_enter(group)
移除任务标识:dispatch_group_leave(group)
追加任务:dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{});
group中任务完成后通知添加指定执行任务:dispatch_group_notify(group, dispatch_get_main_queue(), ^{ }); 异步操作不会阻塞当前线程
等待group中任务完成后继续在当前线程执行后续任务:dispatch_group_wait(group, DISPATCH_TIME_FOREVER); 会阻塞当前线程
信号量 dispatch_semaphore
三种用途:
1、控制并行队列线程并发数
2、保持线程同步,将异步执行任务转换为同步执行任务
3、保证线程安全,为线程加锁
创建信号量:dispatch_semaphore_create(count); count 信号量个数
占用信号量: dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
释放信号量:dispatch_semaphore_signal(semaphore);
计时器实现:dispatch_source_t
创建计时器:dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER,0,0,queue);
设置计时器:dispatch_source_set_timer(timer,dispatch_walltime(nil,0),10*NSEC_PER_MSEC,0);
设置操作事件:dispatch_source_set_event_handler(timer,^{});
开始:dispatch_resume(timer);
暂停:dispatch_suspend(timer);
取消:dispatch_source_cancel(timer); 只能取消尚未执行的任务