GCD开源地址
概念理解
- 任务: 耗时操作-被执行的代码块
- 队列:只允许在一端插入数据操作,在另一端进行删除数据操作的特殊线性表;进行插入操作的
一端称为队尾(入队列),进行删除操作的一端称为队头(出队列);队列具有先进先出(FIFO)的特性。 - 多线程:多线程的并发是用时间片轮转方法实现的,线程创建、销毁、上下文切换等会消耗CPU性能
- 多核:是指在一枚处理器(processor)中集成两个或多个完整的计算引擎资源
- 多核CPU:就是基板上集成有多个单核CPU、核属于cpu的一部分
- 计算机位数:表示不同的平台下的CPU对内存空间的寻址能力
需要特别理解的操作:
1、code->start:任务开始执行的影响因素
2、线程对任务执行的影响
3、任务执行完成的影响
注意:同步任务在同一线程内嵌套加入同一串行队列 会造成死锁;原因:2任务的执行条件是1任务完成、1任务的完成条件是2任务完成
特点
1、任务是否完成阻塞任务所在线程
2、任务是否完成阻塞入队列
3、任务是否完成阻塞队列内后续任务执行
4、加入队列后立即执行-可同时存在多个相同类型任务执行
5、创建线程
6、等待现有异步任务创建的线程闲置
7、使用任务所在线程执行任务
8、任务开始顺序-先进先开始-fifo(任务执行-代码出队列)
串行队列 | 并发队列 | |
---|---|---|
是否允许创建线程 | 异步任务允许创建1个异步线程 | 是 |
同一时间最大活跃线程个数 | 1 | 32/64等 |
任务开始顺序 | 8、 | 8、 |
同步任务 | 1、3、7、 | 1、4、7、 |
异步任务 | 3、5、|6、 | 4、|5、|6、 |
通过以上对比可以看到同类任务在串行、并发队列中表现的不同点就是3、4
Let The Code Say
- (dispatch_queue_t)main_queue{//主队列
return dispatch_get_main_queue();
}
- (dispatch_queue_t)globel_queue{//全局并发队列
return dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
}
- (dispatch_queue_t)con_queue:(const char *_Nullable)label{//并发队列
return dispatch_queue_create(label, DISPATCH_QUEUE_CONCURRENT);
}
- (dispatch_queue_t)ser_queue{//串行队列
return dispatch_queue_create("com.serQueue", DISPATCH_QUEUE_SERIAL);
}
- (void)queueTest {
dispatch_queue_t con_queue = [self con_queue:"com.conQueue1"];
dispatch_queue_t con_queue1 = [self con_queue:"com.conQueue2"];
dispatch_queue_t ser_queue = [self ser_queue];
dispatch_queue_t globel_queue = [self globel_queue];
dispatch_queue_t main_queue = [self main_queue];
// con_queue和globel_queue在作者mac上最大并发是64 猜测最大线程数取决于计算机位数
for (int i =0; i< 100; i++) {
dispatch_async(con_queue, ^{
NSLog(@"dispatch_async_con_queue:%d--- %@",i,[NSThread currentThread]);
sleep(500);
});
}
// 其他线程给主线程通信
- (void)performSelectorOnMainThread:(SEL)aSelector withObject:(id)arg waitUntilDone:(BOOL)wait;
// 线程间通信
- (void)performSelector:(SEL)aSelector onThread:(NSThread *)thread withObject:(id)arg waitUntilDone:(BOOL)wait;
// 串行队列同一时间只会有一个线程处于活跃 同步任务不会开启新的线程 异步任务会开启一个新的线程 (队列无任务时开始销毁线程)任务结束后大概7秒线程销毁
dispatch_async(ser_queue, ^{
NSLog(@"ser_queue1:%@", [NSThread currentThread]);
});
dispatch_sync(ser_queue, ^{
NSLog(@"ser_queue2:%@", [NSThread currentThread]);
});
dispatch_async(ser_queue, ^{
NSLog(@"ser_queue3:%@", [NSThread currentThread]);
});
dispatch_sync(ser_queue, ^{
NSLog(@"ser_queue4:%@", [NSThread currentThread]);
});
sleep(7);
dispatch_async(ser_queue, ^{
NSLog(@"ser_queue6:%@", [NSThread currentThread]);
});
/*
ser_queue1:<NSThread: 0x600000de2000>{number = 6, name = (null)}
ser_queue2:<NSThread: 0x600000dd8340>{number = 1, name = main}
ser_queue3:<NSThread: 0x600000de2000>{number = 6, name = (null)}
ser_queue4:<NSThread: 0x600000dd8340>{number = 1, name = main}
ser_queue6:<NSThread: 0x600000de2000>{number = 4, name = (null)}
*/
// 验证同步任务立即执行的特点
dispatch_async(con_queue, ^{
dispatch_sync(ser_queue, ^{
NSLog(@"----1:%@", [NSThread currentThread]);
sleep(10);
NSLog(@"====1:%@", [NSThread currentThread]);
});
});
dispatch_async(con_queue, ^{
dispatch_async(ser_queue, ^{
NSLog(@"----2:%@", [NSThread currentThread]);
sleep(10);
NSLog(@"====2:%@", [NSThread currentThread]);
});
NSLog(@"2:%@", [NSThread currentThread]);
});
dispatch_async(con_queue, ^{
dispatch_sync(ser_queue, ^{
NSLog(@"----3:%@", [NSThread currentThread]);
sleep(10);
NSLog(@"====3:%@", [NSThread currentThread]);
});
});
/*ser_queue
----1:<NSThread: 0x600000801a00>{number = 5, name = (null)}
2:<NSThread: 0x600000857380>{number = 6, name = (null)}
====1:<NSThread: 0x600000801a00>{number = 5, name = (null)}
----2:<NSThread: 0x6000008019c0>{number = 3, name = (null)}
====2:<NSThread: 0x6000008019c0>{number = 3, name = (null)}
----3:<NSThread: 0x600000812840>{number = 4, name = (null)}
====3:<NSThread: 0x600000812840>{number = 4, name = (null)}
*/
/*con_queue1
----1:<NSThread: 0x600001a20b00>{number = 5, name = (null)}
2:<NSThread: 0x600001a36800>{number = 3, name = (null)}
----3:<NSThread: 0x600001a367c0>{number = 4, name = (null)}
----2:<NSThread: 0x600001a34c40>{number = 6, name = (null)}
====1:<NSThread: 0x600001a20b00>{number = 5, name = (null)}
====2:<NSThread: 0x600001a34c40>{number = 6, name = (null)}
====3:<NSThread: 0x600001a367c0>{number = 4, name = (null)}
*/
网友评论