GCD的基本思想是将操作放在队列中执行
纯C语言
优点
1.为多核的并行运算提出了解决方案
2.自动利用更多的CPU内核
3.自动管理线程的生命周期(创建线程,调度任务,消毁线程)
4.程序员只需要告诉GCD想要执行什么任务,不需要编写任何线程管理代码
二 .任务和队列
GCD使用步骤
*定制任务(确定想做的事情)
*将任务添加到队列中
GCD会自动将队列中的任务取出来,放到对应的线程中执行
任务的取出遵循队列的FIFO原则:先进先出,后进后出 与栈的区别 先进后出
*GCD中有两种方式执行任务的函数
1.同步的方式执行任务
dispatch_sync(<#dispatch_queue_t queue#>, <#^(void)block#>)
queue :队列
block:任务
2.异步的方式执行任务
dispatch_async(<#dispatch_queue_t queue#>, <#^(void)block#>)
queue :队列
block:任务
同步和异步区别
同步:在当前线程中执行(不具备开启线程)
异步:在另一条线程中执行(具备开启线程的能力)
GCD的队列可以分为2大类
1.并发队列(Concurrent DISpathch Queue)
可以让多个任务并发(同时)执行(自动开启多个线程同时执行任务)
并发功能只有在异步(dispatch_async)函数下才有效
2串行队列(serial Dispatch Queue)
让任务一个接着一个地执行(一个任务执行才可以完成下个任务)
凡事函数名带有creat retain copy new 等字眼 都需要在不需要的时候进行release
*主队列 (跟主线程相关的队列)
主队列GCD 自带的一种特殊的串行队列
放在主队列中的任务,都放到主线程中执行
********* 使用dispatch_sync 同步函数,不能主线程中往主队列dispatch_get_main_queue() 添加任务因为在同步函数中会在主线程中是按顺序执行的 会照成死循环
touchesBegan 中添加到主线程队列中 GCD4也添加到主线程队列 touchesBegan等待GCD4完成 GCD4 等待touchesBegan完成
如果是异步dispatch_async 可以缓一缓 不是死循环
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
[self GCD4];
}
#pragma mark 主(线程)队列 保证操作在主线程中执行
-(void)GCD4
{
//每个应用程序只有一个主线程
//为什么需要主线程 ,所有UI的更新工作 都必须在主线程上工作
dispatch_queue_t q=dispatch_get_main_queue()
;
//异步在主线程 在主线程上运行
for (int i=0; i<15; i++) {
dispatch_sync(q, ^{//同步顺序执行仍然依次执行
// NSLog(@"",);//当前线程;
NSLog(@"%@ %d",[NSThread currentThread],i);
});
}
}
#pragma mark dispatch_group_async组 只有等到组内的所有任务都执行完才会调用dispatch_group_notify
-(void)creatGround
{
dispatch_group_t que= dispatch_group_create();
dispatch_group_notify(que, dispatch_get_main_queue(), ^{
NSLog(@"------------");
});
dispatch_group_async(que, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSLog(@"=====");
});
dispatch_group_async(que, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSLog(@"=====");
});
}
#pragma mark 主(线程)队列 保证操作在主线程中执行
-(void)GCD4
{
//每个应用程序只有一个主线程
//为什么需要主线程 ,所有UI的更新工作 都必须在主线程上工作
dispatch_queue_t q=dispatch_get_main_queue()
;
//异步在主线程 在主线程上运行
for (int i=0; i<15; i++) {
//主线程是有工作的 阻塞 而且
//异步任务,在主线程上运行,继续保持队列
dispatch_sync(q, ^{//同步顺序执行仍然依次执行
// NSLog(@"",);//当前线程;
NSLog(@"%@ %d",[NSThread currentThread],i);
});
}
//
for (int i=0; i<5; i++) {
dispatch_async(q, ^{//异步任务,并发执行,当是如果在串行队列依次按顺序执行
NSLog(@"%@ %d",[NSThread currentThread],i);
});
}
//
}
#pragma mark 全局队列(苹果为了方便多线程的设计 提供一个全局队列,供所有APP共同使用)
-(void)GCD3{
//全局队列与并行队列区别
// 1 不需要创建 直接get就能用
// 2.两个队列的执行效果相同
// 3全局队列没有名称 调试时 无法确定对队列
dispatch_queue_t q=dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);//优先级
// for (int i=0; i<5; i++) {
// dispatch_sync(q, ^{//同步顺序执行仍然依次执行
// // NSLog(@"",);//当前线程;
// NSLog(@"%@ %d",[NSThread currentThread],i);
// });
// }
//
for (int i=0; i<5; i++) {
dispatch_async(q, ^{//异步任务,并发执行,当是如果在串行队列依次按顺序执行
NSLog(@"%@ %d",[NSThread currentThread],i);
dispatch_async(dispatch_get_main_queue(), ^{
self.textfrield.text=@"12345678912345678";
});
});
}
}
#pragma mark 串行(一个接一个排队跑步,保持dui)
-(void)GCD
{
//将操作放到队列中
//在C语言函数中,定义类型,绝大多数的结尾时_t或者ref
//使用串行队列,的异步任务非常有用,新建子线程是有开销的,不能无止境新建线程
//既保证效率只有(新建一个子线程)要能够实现并发
dispatch_queue_t q=dispatch_queue_create("zefeng", DISPATCH_QUEUE_SERIAL);
//串行队列的同步任务,会在 “主线程上运行”
// 少用
for (int i=0; i<5; i++) {
dispatch_sync(q, ^{//同步顺序执行仍然依次执行
// NSLog(@"",);//当前线程;
NSLog(@"%@ %d",[NSThread currentThread],i);
});
}
for (int i=0; i<5; i++) {
dispatch_async(q, ^{//异步任务,并发执行,当是如果在串行队列依次按顺序执行
NSLog(@"%@ %d",[NSThread currentThread],i);
});
}
// dispatch_release(q);
}
#pragma mark 并行(并排跑)
-(void)GCD1{
//特点:没有队形,执行顺序程序员不能控制
//应用场景:并发执行任务,没有先后顺序关系
//并行队列容易出错!并行队列不能控制顺序 控制新建线程的数量
dispatch_queue_t q=dispatch_queue_create("xiefeng", DISPATCH_QUEUE_CONCURRENT);//concurrent
for (int i=0; i<3; i++) {
dispatch_sync(q, ^{//同步顺序执行仍然依次执行
// NSLog(@"",);//当前线程;
NSLog(@"%@ %d",[NSThread currentThread],i);
});
}
for (int i=0; i<3; i++) {
dispatch_async(q, ^{//异步
NSLog(@"%@ %d",[NSThread currentThread],i);
});
}
}
操作使用block定义
队列负责调度任务执行所在的线程以及具体的执行时间
队列的特点先进先出,新添加至队列的操作都会排在队尾
提示
GCD的函数都是以(dispatch 分派 调度)开头的
队列
dispatch_queue_t
串行队列 队列中的任务只会按顺序执行
并行队列 队列中任务通常会并发执行
dispatch_async 异步操作 会并发执行,无法确定任务的执行顺序
dispatch_sync 同步操作 会依次顺序执行,能够决定任务的执行顺序
队列不是线程 也不是CPU 队列负责调度 谁空闲就把任务给谁
多线程的目的是为了在CPU上实现快速切换