• iOS 多线程之GCD


    多线程之GCD##

    简介###

    全称:Grand Central Dispatch,大中枢调度
    
    优势:GCD是苹果公司为多核的并行运算提出的解决方案
    	它会自动利用更多的CPU内核,会自动管理线程的生
    	命周期(创建线程,调度任务,销毁线程),它是纯
    	C语言,提供了非常多强大的函数。
    

    概念###

    任务:执行什么操作
    队列:用来存放任务(先进先出,后进后出)
    同步:只能在当前线程中执行任务,不具备开启新线程的能力
    异步:可以在新的线程中执行任务,具备开启新线程的能力
    并发队列:可以让多个任务并发(同时)执行,并发功能只能在异步(dispatch_async)函数下才有效
    串行队列:让任务一个一个地执行
    

    基本使用###

    1.同步串行队列

    //创建同步串行队列并把任务加入队列,没有创建新的子线程,所有任务在主线程上串行执行
    //这样写没有啥意义
    -(void)createSynSerial
    {
    	// 1.自己创建一个串行队列
    	dispatch_queue_t queue = dispatch_queue_create("com.huashan.queue", DISPATCH_QUEUE_SERIAL);
    	
    	//block中的是任务,将任务加到并行队列中,异步队列会开辟出来新的子线程,任务按添加顺序执行
    	dispatch_sync(queue, ^{ 
      	  NSLog(@"++++队列1, %@++++", [NSThread currentThread]);
     	});
    
    	dispatch_sync(queue, ^{
        	NSLog(@"++++队列2, %@++++", [NSThread currentThread]);
    	});
    
    	dispatch_sync(queue, ^{
        	NSLog(@"++++队列3, %@++++", [NSThread currentThread]);  
     });
    }
    


    2.同步并行队列

    //创建同步并行队列并把任务加入队列,不会创建新的线程,都是在当前线程做事情
    //这种方式没啥意义
    -(void)createSynConcurrent
    {
    // 1.自己创建一个并行队列  dispatch_queue_t queue = dispatch_queue_create("com.huashan.queue", DISPATCH_QUEUE_CONCURRENT);
    
    //用系统提供的全局并行队列
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    
    //block中的是任务,将任务加到并行队列中,同步队列不会开辟出来新的子线程
    dispatch_sync(queue, ^{
        for (int i = 0; i < 3; ++i)
        {
            NSLog(@"++++队列1, %@++++", [NSThread currentThread]);
        }
    });
    
    dispatch_sync(queue, ^{
        for (int i = 0; i < 3; ++i)
        {
            NSLog(@"++++队列2, %@++++", [NSThread currentThread]);
        }
    });
    
    dispatch_sync(queue, ^{
        for (int i = 0; i < 3; ++i)
        {
            NSLog(@"++++队列3, %@++++", [NSThread currentThread]);
        }
    });
    NSLog(@"------------看看执行顺序--------------");
    }
    


    3.异步串行队列

    //创建异步串行队列并把任务加入队列,会开启一个新的子线程,任务是串行执行的,完成一个任务,再执行下一个任务
    //这种情况只需要把多个任务加入一个block块中即可
    -(void)createAsySerial
    {
    // 1.自己创建一个串行队列
    dispatch_queue_t queue = dispatch_queue_create("com.huashan.queue", DISPATCH_QUEUE_SERIAL);
    
    //block中的是任务,将任务加到并行队列中,异步队列会开辟出来新的子线程,任务按添加顺序执行
    dispatch_async(queue, ^{
        for (int i = 0; i < 3; ++i)
        {
            NSLog(@"++++队列1, %@++++", [NSThread currentThread]);
        }
    });
    
    dispatch_async(queue, ^{
        for (int i = 0; i < 3; ++i)
        {
            NSLog(@"++++队列2, %@++++", [NSThread currentThread]);
        }
    });
    
    dispatch_async(queue, ^{
        for (int i = 0; i < 3; ++i)
        {
            NSLog(@"++++队列3, %@++++", [NSThread currentThread]);
        }
    });
    NSLog(@"------------看看执行顺序--------------");
    }
    


    4.异步并行队列

    //创建异步并行队列并把任务加入队列,可以同时开辟多条子线程,并发去执行多个任务
    -(void)createAsyConcurrent
    {
    // 1.自己创建一个并行队列  dispatch_queue_t queue = dispatch_queue_create("com.huashan.queue", DISPATCH_QUEUE_CONCURRENT);
    
    //用系统提供的全局并行队列
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    
    //block中的是任务,将任务加到队列中,异步队列会开辟出来新的子线程
    dispatch_async(queue, ^{
        for (int i = 0; i < 3; ++i)
        {
            NSLog(@"++++队列1, %@++++", [NSThread currentThread]);
        }
    });
    
    dispatch_async(queue, ^{
        for (int i = 0; i < 3; ++i)
        {
            NSLog(@"++++队列2, %@++++", [NSThread currentThread]);
        }
    });
    
    dispatch_async(queue, ^{
        for (int i = 0; i < 3; ++i)
        {
            NSLog(@"++++队列3, %@++++", [NSThread currentThread]);
        }
    });
    NSLog(@"------------看看执行顺序--------------");
    }
    

    5.异步主队列

    /**
    * 异步函数 + 主队列:只在主线程中执行任务,并没有开辟新的线程
    * 很少用没啥意义
    */
    - (void)asyncMain
    {
    // 1.获得主队列
    dispatch_queue_t queue = dispatch_get_main_queue();
    
    // 2.将任务加入队列
    dispatch_async(queue, ^{
        for (int i = 0; i < 3; ++i)
        {
            NSLog(@"++++队列1, %@++++", [NSThread currentThread]);
        }
    });
    
    dispatch_async(queue, ^{
        for (int i = 0; i < 3; ++i)
        {
            NSLog(@"++++队列2, %@++++", [NSThread currentThread]);
        }
    });
    
    dispatch_async(queue, ^{
        for (int i = 0; i < 3; ++i)
        {
            NSLog(@"++++队列3, %@++++", [NSThread currentThread]);
        }
    });
    }
    


    6.同步主队列

    /**
    * 同步函数 + 主队列:会阻塞线程
    */
    - (void)syncMain
    {
    NSLog(@"syncMain ----- begin");
    // 1.获得主队列
    dispatch_queue_t queue = dispatch_get_main_queue();
    
    // 2.将任务加入队列
    dispatch_sync(queue, ^{  
        NSLog(@"1-----%@", [NSThread currentThread]);   
    });
    
    dispatch_sync(queue, ^{    
        NSLog(@"2-----%@", [NSThread currentThread]);    
    });
    
    dispatch_sync(queue, ^{    
        NSLog(@"3-----%@", [NSThread currentThread]);     
    });
    
    NSLog(@"syncMain ----- end");
    }
    

    GCD常用函数###

    1. dispatch_barrier_async(dispatch_queue_t queue, dispatch_block_t block);

       -(void)gcdBarrierMethod
       {
       dispatch_queue_t queue = dispatch_queue_create("com.huashan.queue", DISPATCH_QUEUE_CONCURRENT);
      
       dispatch_async(queue, ^{
       	NSLog(@"--------任务1, %@-----------", [NSThread currentThread]);
       });
      
       dispatch_async(queue, ^{
      	 NSLog(@"--------任务2, %@-----------", [NSThread currentThread]);
       });
       
       //等之前任务执行完毕,再执行barrier之后的任务
       dispatch_barrier_async(queue, ^{
       	NSLog(@"--------barrier任务, %@-----------", [NSThread currentThread]);
       });
      
       dispatch_async(queue, ^{
       	NSLog(@"--------任务3, %@-----------", [NSThread currentThread]);
       });
      
       dispatch_async(queue, ^{
       	NSLog(@"--------任务4, %@-----------", [NSThread currentThread]);
       });
      
       dispatch_async(queue, ^{
       	NSLog(@"--------任务5, %@-----------", [NSThread currentThread]);
       });
      
       }
      


    2.dispatch_after(dispatch_time_t when,dispatch_queue_t queue,dispatch_block_t block);

        -(void)gcdAfterMethod
        {
    	    NSLog(@"=========%@==========", [NSThread currentThread]);
    
        //3秒之后执行block块中的任务
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3.0 * NSEC_PER_SEC)), dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
            NSLog(@"+++++++++%@+++++++++", [NSThread currentThread]);
        });
        }
    

    3._dispatch_once(dispatch_once_t *predicate, dispatch_block_t block)

        -(void)gcdOnceMethod
        {
        static dispatch_once_t onceTocken;
    
        //block中的代码在整个程序运行过程中只会执行一次
        dispatch_once(&onceTocken, ^{
            NSLog(@"+++++++%@++++++++++", [NSThread currentThread]);
        });
        }
    

    4.队列组:首先异步执行2个耗时的操作,等执行完毕,再执行第3个操作

    5.遍历

    6.线程间通信

  • 相关阅读:
    USACO2.2 Preface Numbering【思维+打表】
    USACO2.1 Hamming Codes【枚举+二进制处理+输出格式+题意理解】
    USACO1.6 Healthy Holsteins【dfs/bfs 爆搜】
    USACO1.5 Mother's Milk【搜索】
    USACO1.6 Number Triangles [dp-简单dp]
    USACO1.6 回文质数 Prime Palindromes
    泛型简介
    涉及 C#的 foreach问题
    c#委托事件及其讲解
    WPF 打印 包括设置,打印预览,打印等等
  • 原文地址:https://www.cnblogs.com/s-y-j/p/5913339.html
Copyright © 2020-2023  润新知