多线程-GCD

GCD:是4.0新增的,C语言写的,他是苹果公司为多核CPU的并行运算提高效率出现的,能够自动管理线程的生命周期,不需要我们对线程的管理。

1.任务和队列
GCD的核心是任务和队列的概念
任务:分为同步任务sync顺序执行,异步任务async开启线成。
队列:串行队列 顺序执行, 并发队列 开启线程。

2.相关API

1).队列

全局主队列系统提供(串行)
dispatch_queue_t  queue = dispatch_get_main_queue()

全局并发队列系统提供

/*参数一队列优先级
#define DISPATCH_QUEUE_PRIORITY_HIGH 2 // 高

#define DISPATCH_QUEUE_PRIORITY_DEFAULT 0 // 默认(中)

#define DISPATCH_QUEUE_PRIORITY_LOW (-2) // 低

#define DISPATCH_QUEUE_PRIORITY_BACKGROUND INT16_MIN // 后台添加同步任务
参数二:队列名称 设为0就好
*/
dispatch_queue_t queue = dispatch_get_global_queue(0,0);



自定义创建队列
/参数一:队列表示符0表示
参数二:队列类型 
DISPATCH_QUEUE_SERIAL串行队列
DISPATCH_QUEUE_COUNNET 并行队列
/
dispatch_queue_t   queue = dispatch_queue_creat(@“”,表示队列类型)


2).创建任务
同步任务 
dispatch_sync(queue,^{
//代码
});
异步任务
dispatch_async(queue,^{

})

3.代码测试
1.同步+串行队列

 //创建同步队列 SERIAL串行队列 COUNNET并发队列
    dispatch_queue_t queue = dispatch_queue_create("name", DISPATCH_QUEUE_SERIAL);
    
    dispatch_sync(queue, ^{
        //执行代码
        
        for (NSInteger i=0; i<100; i++) {
            
            NSLog(@"1--%@",[NSThread currentThread]);
        }
    });
    
    
    
    dispatch_sync(queue, ^{
        for (NSInteger i=0; i<10; i++) {
            
            NSLog(@"2---%@",[NSThread currentThread]);
        }
    });
    
    
    NSLog(@"结束回归主线程");

总结:同步+串行队列 只有一个条线程,不会开启新的线程。任务一个一个执行。

  1. 同步+并发
 dispatch_queue_t queue1 = dispatch_queue_create("chuan", DISPATCH_QUEUE_CONCURRENT);
    
        dispatch_sync(queue1, ^{
    
            for (NSInteger i=0; i<10; i++) {
    
                NSLog(@"同步并发任务1---%@",[NSThread currentThread]);
            }
    
        });
    
        dispatch_sync(queue1, ^{
    
            for (NSInteger i=0; i<10; i++) {
    
                NSLog(@"同步并发任务2---%@",[NSThread currentThread]);
            }
    
        });

总结:同步+并发队列 不开启新线程,在主线程执行按顺序执行

3.异步+串行

 //创建串行队列  serial串行
    dispatch_queue_t queue2 = dispatch_queue_create("yibu", DISPATCH_QUEUE_SERIAL);
    //创建异步任务
        dispatch_async(queue2, ^{
            for (NSInteger i=0; i<10; i++) {
    
                NSLog(@"异步串行任务1---%@",[NSThread currentThread]);
            }
        });
    
        dispatch_async(queue2, ^{
            for (NSInteger i=0; i<10; i++) {
    
                NSLog(@"异步串行任务2---%@",[NSThread currentThread]);
            }
        });

总结:异步任务+串行队列 会开启新线程,按顺序执行

4.异步任务+并行队列

    //并发队列
    dispatch_queue_t queue3 = dispatch_queue_create("yi", DISPATCH_QUEUE_CONCURRENT);
    //异步任务
    dispatch_async(queue3, ^{
                for (NSInteger i=0; i<10; i++) {
        
                    NSLog(@"异步并发任务1---%@",[NSThread currentThread]);
                    //延迟操作
                    [NSThread sleepForTimeInterval:3];
        
                }
    });
    
    
    dispatch_async(queue3, ^{
                for (NSInteger i=0; i<10; i++) {
        
                    NSLog(@"异步并发任务2---%@",[NSThread currentThread]);
                    [NSThread sleepForTimeInterval:5];
                }
    });

总结:异步任务+并行队列 会开启多条线程,任务同时执行,但是没有顺序,没有顺序,没有顺序

5.异步任务+并行队列 按顺序执行
需要使用栅栏函数

创建并行队列
 dispatch_queue_t queuebirrer = dispatch_queue_create("birrer", DISPATCH_QUEUE_CONCURRENT);
//创建同步任务
 dispatch_async(queuebirrer, ^{
        for (NSInteger i=0; i<5; i++) {
            
            //  NSLog(@"异步并发任务1---%@",[NSThread currentThread]);
            [NSThread sleepForTimeInterval:2];
        }
    });
//创建栅栏函数
 dispatch_barrier_async(queuebirrer, ^{
        for (NSInteger i=0; i<5; i++) {
            
            // NSLog(@"异步并发栅栏函数任务2---%@",[NSThread currentThread]);
            [NSThread sleepForTimeInterval:2];
        }
    });

总结:使用栅栏函数可以使 异步任务+并行队列按顺序执行

6.主队列(串行)+同步

 dispatch_queue_t mainqueue = dispatch_get_main_queue(); //串行队列

  dispatch_sync(mainqueue, ^{
    
            for (int i = 0; i < 4; ++i) {
                [NSThread sleepForTimeInterval:2];
                NSLog(@"主队列+同步1---%@",[NSThread currentThread]);
            }
        });
        dispatch_sync(mainqueue, ^{
    
            for (int i = 0; i < 3; ++i) {
                [NSThread sleepForTimeInterval:2];
                NSLog(@"主队列+同步2---%@",[NSThread currentThread]);
            }
        });

总结: 同步任务+串行主队列 会堵塞主线程,程序崩溃,在其他线程不会奔溃

7.主队列+异步任务

 dispatch_queue_t mainqueue = dispatch_get_main_queue(); //串行队列
        dispatch_async(mainqueue, ^{
            for (int i = 0; i < 4; ++i) {
                [NSThread sleepForTimeInterval:2];
                NSLog(@"主队列+异步1---%@",[NSThread currentThread]);
            }
        });
    
    
        dispatch_async(mainqueue, ^{
            for (int i = 0; i < 4; ++i) {
                [NSThread sleepForTimeInterval:2];
                NSLog(@"主队列+异步2---%@",[NSThread currentThread]);
            }
        });

总结:异步任务+主队列 不开启新线程,任务一个一个执行

8.线程间通信
线程间通信指的是子线程与主线程之间的通信

    //全局并发队列
    dispatch_queue_t   globorqQueue = dispatch_get_global_queue(0, 0);
   //主队列
    dispatch_queue_t mainQueue = dispatch_get_main_queue();

 dispatch_async(globorqQueue, ^{
    
            for (int i = 0; i <10; ++i) {
                [NSThread sleepForTimeInterval:2];
                NSLog(@"全局并发队列------%@",[NSThread currentThread]);
            }
            //回归主线程
            dispatch_async(mainQueue, ^{
    
                NSLog(@"线程执行完毕来兄弟告诉我执行玩了没,玩了我就刷新控件了");
    
            });
            });

9.延迟函数 dispatch_after

延迟2秒执行
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0*NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        
    });

10一次性函数 dispatch_once_t 经常用于创建单列

     static dispatch_once_t onceKey;
        dispatch_once(&onceKey, ^{
           // manage = [[manage alloc]init];
    
        });

11.队列组 dispatch_group 当子线程异步任务执行完毕后,回归主线程

 //创建队列组
    dispatch_group_t group = dispatch_group_create();
    //创建全局并发队列
    dispatch_queue_t gqueue = dispatch_get_global_queue(0, 0);

 //调用异步队列组,参数一队列组,参数二全局并发队列
        dispatch_group_async(group, gqueue, ^{
    
            for (int i = 0; i < 2; ++i) {
                [NSThread sleepForTimeInterval:2];
                NSLog(@"异步全局队列组任务1---%@",[NSThread currentThread]);
            }
    
    
        });
    
        dispatch_group_async(group, gqueue, ^{
             for (int i = 0; i < 2; ++i) {
                [NSThread sleepForTimeInterval:2];
                NSLog(@"异步全局队列组任务2---%@",[NSThread currentThread]);
            }
        });



   //上面任务执行完毕回到主线程:参数一:队列组,参数二全局主队列
        dispatch_group_notify(group, dispatch_get_main_queue(), ^{
            NSLog(@"好了你们子线程都执行完毕了该我主线程更新ui");
        });

12.暂停线程 dispatch_wait 堵塞当前线程,等指定队列组任务执行完毕才会继续执行

dispatch_group_t wgroup = dispatch_group_create();
dispatch_queue_t wqueue = dispatch_get_global_queue(0, 0);


     dispatch_group_async(wgroup,wqueue, ^{
            for (int i = 0; i < 2; ++i) {
                [NSThread sleepForTimeInterval:2];
                NSLog(@"异步全局队列组任务wait1---%@",[NSThread currentThread]);
            }
        });
    
    
        dispatch_group_async(wgroup, wqueue, ^{
            for (int i = 0; i < 2; ++i) {
                [NSThread sleepForTimeInterval:2];
                NSLog(@"异步全局队列组任务wait 2---%@",[NSThread currentThread]);
            }
        });
    
//DISPATCH_TIME_NOW(即使上面的队列组中任务未完成也会执行下面的方法)
    //DISPATCH_TIME_FOREVER 上面队列组任务执行完毕以后才会执行下面的方法
 dispatch_group_wait(wgroup, DISPATCH_TIME_FOREVER);
    
    NSLog(@"wait---上面执行完毕就是我了😄");

13.信号量dispatch_semaphore_t 主要作用解决线程同步的问题
个人理解当信号量大于1那么继续执行,小于1那么堵塞不执行
dispatch_semaphroe_signal和dispatch_semaphore_wait成对出现

 dispatch_semaphore_t semaphore = dispatch_semaphore_create(2);
  __block int number = 10;
  //全局并发队列
 dispatch_queue_t queue9 = dispatch_get_global_queue(0, 0);

 dispatch_async(queue9, ^{
        
        dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
        for (int i = 0; i < 10; ++i) {
            [NSThread sleepForTimeInterval:2];
            NSLog(@"信号量---%@",[NSThread currentThread]);
        }
        number = 20;
        //下面这个函数是当该线程执行完毕让线程的信号量+1执行下面的方法,当不添加这句的话会不走下面的函数
        dispatch_semaphore_signal(semaphore);
    });

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章