iOS之线程(二)GCD
程序员文章站
2024-03-24 22:35:16
...
概念
- GCD:Gtand Central Dispatch 中枢调度器
- GCD主要解决的是多核并行运算
- GCD是自动管理线程的生命周期的
任务
- 要执行的操作
- 同步函数:在当前线程中执行任务,
不具备
开启新线程的能力 - 异步函数:可以在新的线程中执行任务,
具备
开启新线程的能力
队列
- 用来存放任务
- 并发队列(异步函数才有效)
- 串行队列
一般使用情况
- 声明一个任务
- 将任务添加到队列中
- GCD会自动将
队列中的任务取出
,放到对应的线程
中去 - 任务要遵循队列的
FIFO
原则,先进先出,后进后出
- GCD会自动将
使用 | 并发队列 | 串行队列 | 主队列 |
---|---|---|---|
异步函数 | 【1】具备开启新线程的能力【2】开启新的线程,任务异步执行 | 【1】具备开启线程的能力【2】会开线程,开一条线程,队列中的任务是按照先后顺序执行 | 【1】不会开启新的线程 【2】串行执行 |
同步函数 | 【1】不会开启新的线程【2】串行执行任务 | 【1】不会开启新的线程【2】串行执行任务 | 【1】如果在主线程中执行会发生死锁 【2】在子线程可以 |
异步函数并发队列
- 异步函数 :具备开启新线程的能力
- 异步函数 + 并发队列 ->开新线程,队列中的任务是异步执行
/*
参数一: C语言的字符串,标识符用来区分队列
参数二: 队列的类型
DISPATCH_QUEUE_CONCURRENT 并发队列
DISPATCH_QUEUE_SERIAL 串行队列
*/
//创建一个队列
dispatch_queue_t queue = dispatch_queue_create("www.cc.com", DISPATCH_QUEUE_CONCURRENT);
//声明任务
//第一个参数:队列
//要执行的任务
// dispatch_async(dispatch_queue_t queue, dispatch_block_t block);
dispatch_async(queue, ^{
NSLog(@"111111,--%@",[NSThread currentThread]);
});
注意: 一个队列中可以.可以添加多个任务,CGD开启线程是不受控制的,不是说有多少个任务就开启多少条线程,具体的是系统内部决定的
异步函数 串行队列
- 异步函数 :具备开启新线程的能力
- 异步函数 + 串行队列: 会开线程,开一条线程,队列中的任务是按照先后顺序执行
//创建串行队列
dispatch_queue_t queue = dispatch_queue_create("cc", DISPATCH_QUEUE_SERIAL);
//创建异步函数任务
dispatch_async(queue, ^{
NSLog(@"2222222--%@",[NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"3333--%@",[NSThread currentThread]);
});
其实上面的创建的并发队列,可以换成系统的
全局并发队列
,区别:上面是自己手动创建
的并发队列,下面是获取系统的
//获取全局并发队列
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
同步函数+并发队列
- 同步函数:不具备开启新线程的能力
- 同步函数+并发队列:不会开启子线程,串行执行任务
//创建队列
dispatch_queue_t queue = dispatch_queue_create("hhh", DISPATCH_QUEUE_CONCURRENT);
//创建任务
//同步函数
dispatch_sync(queue, ^{
NSLog(@"999--%@",[NSThread currentThread]);
});
// 999--<NSThread: 0x60000155a240>{number = 1, name = main}
同步函数+串行队列
- 同步函数:不具备开启新线程的能力
- 同步函数+串行队列:不会开启新的线程
//创建队列
dispatch_queue_t queue = dispatch_queue_create("kkk", DISPATCH_QUEUE_SERIAL);
//同步函数
dispatch_sync(queue, ^{
NSLog(@"%@",[NSThread currentThread]);
});
主队列
- 主队列是GCD自带的一种比较特殊的串行队列
- 在主队列中的任务,都是在主线程中执行的
- 获取主队列
dispatch_get_main_queue()
异步函数+主队列
- 不会开启子线程
// 获取主队列
dispatch_queue_t queue = dispatch_get_main_queue();
//异步函数执行
dispatch_async(queue, ^{
NSLog(@"%@",[NSThread currentThread]);
});
同步函数+主队列
- 同步函数:不具备开启新线程能力,立马执行,如果这个任务没有执行完,不会执行下一个任务
- 产生:死锁
// 获取主队列
dispatch_queue_t queue = dispatch_get_main_queue();
//异步函数执行
dispatch_sync(queue, ^{
NSLog(@"%@",[NSThread currentThread]);
});
线程之间的通信
- 只要是主队列一定是在主线程执行的
- (void)setup7 {
//1.获取全局并发队列
dispatch_queue_t globalQue = dispatch_get_global_queue(0, 0);
//异步函数执行
dispatch_async(globalQue, ^{
//URL
NSURL *url = [NSURL URLWithString:@"https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1559637616849&di=ac9047efc5fb0dbe9eb8d55e321ac4a5&imgtype=0&src=http%3A%2F%2Fmmbiz.qpic.cn%2Fmmbiz_jpg%2FzfDDxwQnD2Qib4s4tN6tVjeD9TXIedpicIZvKjL1u6MfRicUeAx9t31HLBrh11bfxhbiakH0te22TicfmCZgbErp3Gw%2F640%3Fwx_fmt%3Djpeg"];
//回去二进制数据
NSData *data = [NSData dataWithContentsOfURL:url];
UIImage *image = [UIImage imageWithData:data];
//g回到主队列s刷新界面
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@"回到主队列");
self.imgageView.image = image;
});
});
}
####GCD任务加强
//任务加强
- (void)demo1{
//获取并发队列
dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
//包装
void(^task)(void) = ^{
dispatch_sync(queue, ^{
NSLog(@"1111---同步--%@",[NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"2222---异步步--%@",[NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"33333---异步步--%@",[NSThread currentThread]);
});
};
//执行任务
dispatch_async(queue, task);
}
CGD任务组
- (void)demo1{
//创建队列
dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
//创建任务组
dispatch_group_t group = dispatch_group_create();
//异步
dispatch_group_async(group, queue, ^{
NSLog(@"AAAA");
});
//异步
dispatch_group_async(group, queue, ^{
NSLog(@"bbbb");
});
//异步
dispatch_group_async(group, queue, ^{
NSLog(@"CCCC");
});
//这个任务组完成的通知
dispatch_group_notify(group, queue, ^{
NSLog(@"所有的任务完成");
});
NSLog(@"11111");
}
上一篇: HDU-5512-Pagodas