多线程 GCD

来源:互联网 发布:python 小波变换 编辑:程序博客网 时间:2024/04/28 02:25
CGD 全称 Grand Central Dispatch;

1.全局队列异步执行
- (void)demfor{
   
//全局队列负责调度任务的
   
dispatch_queue_tp  = dispatch_get_global_queue(0,0);
   
// 2. 任务 使用block 来包装任务
   
//block 没有参数,没有返回值
   
void (^laty)() = ^{
       
NSLog(@"%@",[NSThreadcurrentThread]);
    };
   
//指定执行执行任务的函数
   
dispatch_async(p, laty);
 
}
2. 全局队列同步执行

- (
void)demfor1{
   
//全局队列负责调度任务的
   
dispatch_queue_tp  = dispatch_get_global_queue(0,0);
   
// 2. 任务 使用block 来包装任务
   
//block 没有参数,没有返回值
   
void (^laty)() = ^{
       
       
NSLog(@"%@",[NSThreadcurrentThread]);
            };
   
//指定执行执行任务的函数
   
dispatch_sync(p, laty);

}
小结: 
同步不开线程 就在当前线程执行
异步开线程, 在其他线程执行block
//精装版异步
- (
void)demfor2{
dispatch_async(dispatch_get_global_queue(0,0), ^{
      NSLog(@"%@",[NSThreadcurrentThread]);
   });
}
//精装版同步
- (
void)demfor3{
    
dispatch_sync(dispatch_get_global_queue(0,0), ^{
        
NSLog(@"%@",[NSThreadcurrentThread]);
     });
}
三.复用证明
//能够体现出GCD底成是有线程池的
// 一个线程执行完了之后,是可以被复用的
//如果用NSThread需要自己维护线程池,已经管理所有线程的生命周期
//在实际开发中新建线程是一个非常繁琐的工作
- (
void)demfor4{
   
for (int i = 0; i <20; i++) {
         
dispatch_async(dispatch_get_global_queue(0,0), ^{
     
NSLog(@"%@",[NSThreadcurrentThread]);
  });
    }
}
四.线程间通讯
//线程间通讯
- (
void)demfor5{
dispatch_async(dispatch_get_global_queue(0,0), ^{
    // 做耗时的操作
      
NSLog(@"耗时的操作%@",[NSThreadcurrentThread]);
    
//通知主线程更新UI
     
dispatch_async(dispatch_get_main_queue(), ^{
         
NSLog(@"更新UI%@",[NSThreadcurrentThread]);
      });
  
   });
  
}
五.串行队列
   串行队列,异步执行
 提问:开线程??开几条come
 
猜测 ,不确定不确定
 */

- (
void)demfor7{

   
//1.参数,队列的名称类似于NSTHreadname属性 是一个C语言的字符串
   
//2. 队列的属性DISPATCH_QUEUE_CONCURRENT并发队列
                
//DISPATCH_QUEUE_SERIAL  串行队列
   
   
//串行
   
dispatch_queue_tp = dispatch_queue_create("fjn",DISPATCH_QUEUE_SERIAL);
   
// 2 执行任务的函数
   
//10 个异步
   
for (int i =0; i <10; i++) {
       
   
   
dispatch_async(p, ^{
       
NSLog(@"%@",[NSThreadcurrentThread]);
    });
       
NSLog(@"fdsfdg");
    }
}
六:串行队列
   串行队列 同步执行
 提问:开线程??开几条come
 
猜测不开,没有最后
 */
 (void)demfor7{

   
//1.参数,队列的名称类似于NSTHreadname属性 是一个C语言的字符串
   
//2. 队列的属性DISPATCH_QUEUE_CONCURRENT并发队列
                
//DISPATCH_QUEUE_SERIAL  串行队列
   
   
//串行
   
dispatch_queue_tp = dispatch_queue_create("fjn",DISPATCH_QUEUE_SERIAL);
   
// 2 执行任务的函数
   
//10 个异步
   
for (int i =0; i <10; i++) {
       
   
   
dispatch_sync(p, ^{
       
NSLog(@"%@",[NSThreadcurrentThread]);
    });
       
NSLog(@"fdsfdg");
    }
}

七:并行队列
  异步任务
//猜测开线程嘛?
//开线程N条线程
//开线程 线程条数由GCD决定

- (void)demfor8{
 
   dispatch_queue_t p = dispatch_queue_create("itchit",DISPATCH_QUEUE_CONCURRENT);
   for (int i = 0; i <10; i++) {
       
   
   
dispatch_async(p, ^{
       
NSLog(@"%@ %d",[NSThreadcurrentThread],i);
    });

    }
}
八:
并行队列并发队列和串行队列同步执行任务结果一样
  同步任务
//猜测开线程嘛?
//不开不开
- (
void)demfor9{
   
   
dispatch_queue_tp = dispatch_queue_create("itchit",DISPATCH_QUEUE_CONCURRENT);
   
for (int i = 0; i <10; i++) {
       
       
       
dispatch_sync(p, ^{
           
NSLog(@"%@ %d",[NSThreadcurrentThread],i);
        });
       
    }
}
//阶段性小结:
/**
 *
开不开线程 和执行任务的函数有关
 -
同步不开
 -
异步开
 2 (
异步)开几条线程和队列有关
  -
串行开一条
  -
并发开N具体条数由GCD决定
 */
七:主队列
主队列的概念,只要主队列有任务就不会调度
主队列,异步执行
// 1,队列 - 程序一启动 主线程就已经存在,主队列也同时就存在了,只需要或获取不需要创建
   
dispatch_queue_tp = dispatch_get_main_queue();
   
//异步执行
   
dispatch_async(p, ^{
       
for (int i = 0; i <10; i++) {
        
           
NSLog(@"%@ -- %d",[NSThreadcurrentThread],i);
        }
    });
   
   
NSLog(@"睡会");
    [
NSThreadsleepForTimeInterval:1];
   NSLog(@"232");
主队列,同步执行
//会造成死锁,因为主队列和同步都在等待
- (
void)dowlton1{
 
   
dispatch_queue_tp = dispatch_get_main_queue();
   
//同步执行
   
dispatch_sync(p, ^{
       
for (int i = 0; i <10; i++) {
           
           
NSLog(@"%@ -- %d",[NSThreadcurrentThread],i);
        }
    });
}
实现同步执行的用处
写一个例子:用户登录 下载A 下载B
 要求 必须用户登录成功后,才允许下载 
 dispatch_queue_t  p =dispatch_queue_create("zhujin",DISPATCH_QUEUE_CONCURRENT);
  
//同步执行任务作用- 作用可以让一些异步执行的任务,依赖,某一个特殊的任务用户登录();
   
dispatch_sync(p, ^{
       
NSLog(@"登录%@", [NSThread currentThread]);
    });
   
dispatch_async(p, ^{
       
NSLog(@"A%@", [NSThreadcurrentThread]);
    });
   
dispatch_async(p, ^{
       
NSLog(@"b%@", [NSThreadcurrentThread]);
    });   
}


 
2.上面的(登录)耗时操作写在了主线程,这明显不行
增强版 block
/提示 通过block 的嵌套,能够让任务非常的负责
   
//复杂到,很难用一张表格来描述各种组合
   
//需要理解队列的执行函数的特点
//    同步任务是在当前,没有规定一定在主线程
//队列
   
 
dispatch_queue_t  p =dispatch_queue_create("zhujin",DISPATCH_QUEUE_CONCURRENT);

   
void (^ta)() = ^{
   
//任务
       
dispatch_sync(p, ^{
           
NSLog(@"登录%@", [NSThread currentThread]);
        });
       
dispatch_async(p, ^{
           
NSLog(@"A%@", [NSThreadcurrentThread]);
        });
       
dispatch_async(p, ^{
           
NSLog(@"b%@", [NSThreadcurrentThread]);
        });

    };
   
//异步执行ta
   
dispatch_async(p, ta);
}

3.主队列同步任务不死锁的操作
- (void)tofds2{
 
   
dispatch_queue_t  p =dispatch_queue_create("zhujin",DISPATCH_QUEUE_CONCURRENT);

   
void(^ta)() = ^{

    
dispatch_sync(dispatch_get_main_queue(), ^{
        
NSLog(@"com,here %@",[NSThreadcurrentThread]);
     });
       
NSLog(@"hahah,%@",[NSThreadcurrentThread]);
    };

   dispatch_async(p, ta);


}
八.全局队列队列和串行队列的选择
八.全局队列队列和并行队列的选择

  九.延迟的操作和参数讲解

 9.一次性执行代码
一次性执行->有时候,在程序开发是,会希望一部分代码,从程序启动后,只会被执行一次

最常用的一个场景,单列:在内存中只有唯一的一个副本
- (void)once{
 //dispatch_once_t能够保证block中的嗲吗,只会被执行一次
//oncetoken == 0 就是执行block的代码
// dispatch_once是线程安全的
// 只要涉及到线程安全,就会涉及到锁,dispatch_once内部也有不把锁,性能会比互斥锁高
   static dispatch_once_t onceToken;

//block 是同步的
//能够保证后续的代码直接使用 block 执行后的结果
   dispatch_once(&onceToken, ^{
要执行一次的代码
       NSLog(@"是一次嘛?%@",[NSThreadcurrentThread]);
    });
}
//判断同步/异步 小技巧
NSLog(@"come here");

MArk 调度组
/**
 
目的:为了后续网络功能的一个扩展,AFN框架(有名的网络框架)
 */

// The dispatch_group_async() convenience function behaves like so:
// dispatch_group_async()是一个方便的函数,类似于以下代码
/**
void dispatch_group_async(dispatch_group_t group, dispatch_queue_t queue, dispatch_block_t block)
{
    dispatch_retain(group);
    dispatch_group_enter(group);
    dispatch_async(queue, ^{
        block();
        dispatch_group_leave(group);
        dispatch_release(group);
    });
}
*/

// 知道就行!
- (
void)group2 {
   
   
// 1. 群组-统一监控一组任务
   
dispatch_group_tgroup = dispatch_group_create();
   
   
dispatch_queue_tq = dispatch_get_global_queue(0,0);
   
   
// 1> 入组 -> 之后的 block 会被 group 监听
   
// dispatch_group_enter一定和 dispatch_group_leave 要配对出现
   
dispatch_group_enter(group);
   
dispatch_async(q, ^{
       
NSLog(@"task1 %@", [NSThreadcurrentThread]);
       
       
// block的末尾,所有任务执行完毕后,添加一个出组
       
dispatch_group_leave(group);
    });
   
// 2> 再次入组
   
dispatch_group_enter(group);
   
dispatch_async(q, ^{
        [
NSThreadsleepForTimeInterval:1.0];
       
       
NSLog(@"task2 %@", [NSThreadcurrentThread]);
       
       
// block的末尾,所有任务执行完毕后,添加一个出组
       
dispatch_group_leave(group);
    });
   
   
// 3. 群组结束
   
dispatch_group_notify(group,dispatch_get_main_queue(), ^{
       
NSLog(@"OVER");
    });
   
   
// 4. 群组等待 -> 等到永远,死等,等到所有任务完成
   
// 阻塞式的等待,群组任务不执行完,后续代码无法执行!
   
// (知道就)
//    dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
   
   
NSLog(@"come here");
}

// MARK: 调度组
// 应用场景:需要在所有异步任务执行完毕后,统一获得一个通知!
// 新浪微博提前将所有的缩略图(2k~3k)下载到本地,统一刷新表格,就可以针对不同的图片宽高设计UI
// 如果图片在服务器上,是无法直接获得宽高
- (
void)group1 {
   
// 1. 群组-统一监控一组任务
   
dispatch_group_tgroup = dispatch_group_create();
   
   
dispatch_queue_tq = dispatch_get_global_queue(0,0);
   
// 2. 添加任务
   
// group 负责监控任务,queue 负责调度任务
   
dispatch_group_async(group, q, ^{
        [
NSThreadsleepForTimeInterval:1.0];
       
NSLog(@"任务1 %@", [NSThreadcurrentThread]);
    });
   
dispatch_group_async(group, q, ^{
       
NSLog(@"任务2 %@", [NSThreadcurrentThread]);
    });
   
dispatch_group_async(group, q, ^{
       
NSLog(@"任务3 %@", [NSThreadcurrentThread]);
    });
   
   
// 3. 监听所有任务完成 等到 group 中的所有任务执行完毕后,"由队列调度block 中的任务异步执行!"
   
dispatch_group_notify(group,dispatch_get_main_queue(), ^{
       
// 修改为主队列,后台批量下载,结束后,主线程统一更新UI
       
NSLog(@"OK %@", [NSThreadcurrentThread]);
    });
   
   
NSLog(@"come here");
}


0 0
原创粉丝点击