zoukankan      html  css  js  c++  java
  • 多线程二(GCD)代码笔记

    //
    //  TWFXViewController.h
    //  Demo_GCD
    //
    //  Created by Lion User on 12-12-11.
    //  Copyright (c) 2012年 Lion User. All rights reserved.
    //
    
    #import <UIKit/UIKit.h>
    
    @interface TWFXViewController : UIViewController
    
    @property (retain, nonatomic) IBOutlet UILabel *outletLabel1;
    @property (retain, nonatomic) IBOutlet UILabel *outletLabel2;
    @property (retain, nonatomic) IBOutlet UILabel *outletLabel3;
    @property (retain, nonatomic) IBOutlet UILabel *outletLabel4;
    
    - (IBAction)btnClick4:(UIButton *)sender;
    - (IBAction)btnClick2:(UIButton *)sender;
    - (IBAction)btnClick3:(UIButton *)sender;
    - (IBAction)btnClick:(UIButton *)sender;
    @end
    //
    //  TWFXViewController.m
    //  Demo_GCD
    //
    //  Created by Lion User on 12-12-11.
    //  Copyright (c) 2012年 Lion User. All rights reserved.
    //
    /*
     GCD(系统管理线程) 简介
     使用GCD你不需要编写线程代码,只需定义想要执行的任务,然后添加到适当的 dispatch queue (调度队列)里
     GCD会负责创建线程和调度你的任务.系统直接提供线程管理,比应用实现更高效
     
     基于C的执行自定义任务机制,dispatch queue 按先进先出的顺序,串行或并发地执行任务.dispatch queue 分以下三种:
     serial dispatch queue : 串行调度队列,一次只执行一个任务,直到当前任务完成才开始出列并启动下一个任务
                             主要用于对特定资源的同步访问.虽然每个串行queue本身每次只能执行一个任务,但各个串行queue之间是并发执行的
     concurrent dispatch queue: 也称为 global dispatch queue, 并行调度队列,并发执行一个或多个任务,但启动顺序仍是按照添加到queue的顺序启动
                                你不能创建并发dispatch queues, 只能使用系统已经定义好了的三个全局并发queues,具体下面说到
     main dispatch queue : 全局可用的串行 queue,在应用主线程中执行任务,比如用于刷新UI界面
     
     
     dispatch queue 相关的技术
     Dispatch group : 用于监控一组block对象完成
     Dispatch semaphore : 类似于传统的 semaphore (信号量)
     Dispatch Source : 系统事件异步处理机制
     
     dispatch queue 中的 各个线程,可以通过queue的context指针来共享数据
     
     */
    
    
    #import "TWFXViewController.h"
    
    @interface TWFXViewController ()
    
    @end
    
    @implementation TWFXViewController
    
    - (void)viewDidLoad
    {
        [super viewDidLoad];
        // Do any additional setup after loading the view, typically from a nib.
    }
    
    - (void)didReceiveMemoryWarning
    {
        [super didReceiveMemoryWarning];
        // Dispose of any resources that can be recreated.
    }
    
    
    /*
     全局并发 Dispatch queue
     1. 并发 dispatch queue 可以同时并发执行多个任务,不过并发 queue 仍然按照先进先出的顺序启动任务
     2. 并发 queue 同时执行的任务数量会根据应用和系统动态变化,各个因素如:可用核数量  其他进程正在执行的工作数量 其他串行dispatch queue 中的优先任务的数量等
     3. 系统会给每个应用程序提供三个并发 dispatch queue,全局共享,三个queue的唯一区别在于优先级不同 
     */
    - (IBAction)btnClick4:(UIButton *)sender {
        
        /*
         获取全局并发 dispatch queue : dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)
         第一个参数表示 queue 的优先级,这里获取默认优先级的那个queue,也可以获取高/低优先级的那个,把 DEFAULT 换成 HIGH 或 LOW 就行了
         第二个参数表示 ?
         */
        dispatch_queue_t aQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
        
        
        //把一个block加入到全局并发调度队列里
        dispatch_async(aQueue, ^(void) {
                    
            for (int i = 0; i < 1000; i++) {
                
                //把block同步添加到主线程里,这样子,demo queue 就会暂停等这个block执行完成才继续执行
                dispatch_sync(dispatch_get_main_queue(), ^(void) {
                    
                    NSString *text = [NSString stringWithFormat:@"%d", i];
                    self.outletLabel3.text = text;
                });            
            }
            
        });
        
        
        //把另一个block加入到全局并发调度队列里.这个block和上面那个block会并发执行
        dispatch_async(aQueue, ^(void){
            
            for (int i = 0; i < 1000; i++) {
                
                //把block同步添加到主线程里,这样子,demo queue 就会暂停等这个block执行完成才继续执行
                dispatch_sync(dispatch_get_main_queue(), ^(void) {
                    
                    NSString *text = [NSString stringWithFormat:@"%d", i];
                    self.outletLabel4.text = text;
                });
            }
            
        });
        
    }
    
    
    /*
     串行 Dispatch queue
     1. 串行 queue 每次只能执行一个任务,可以使用它来代替锁,保护共享资源或可变的数据结构,串行queue确保任务按可预测的顺序执行(这是比锁好的地方)
     2. 必须显式创建和管理所有你使用的串行queue(数目任意)
     */
    - (IBAction)btnClick2:(UIButton *)sender {
        
        /*
         使用 dispatch_queue_create() 方法来创建串行queue
         第一个参数表示 queue 的名字, 第二个参数表示 queue 的一组属性(保留给将来使用)
         */
        dispatch_queue_t queue = dispatch_queue_create("demo queue", NULL);
        
        
        /*
         异步调度和同步调度
         异步调度 dispatch_async : 把一个任务添加到某queue后就马上离开,而不管任务在那个queue里的执行状态
         同步调度 dispatch_sync : 把一个任务添加到某queue后,等这个任务完成,调用线程才继续执行.尼玛,坑爹啊
         
         所以,异步调度和同步调度的区别不在于被添加的任务怎样执行,而在于调用线程是否等待任务执行完
         */
        
        //把block异步添加到上面创建的名为 demo queue 的调度队列里
        dispatch_async(queue, ^(void){
            
            for (int i = 0; i < 1000; i++) {
    
             //   sleep(1);
              //  printf("a%d	",i);
                
                //把block同步添加到主线程里,这样子,demo queue 就会暂停等这个block执行完成才继续执行
                dispatch_sync(dispatch_get_main_queue(), ^(void) {
    
                    NSString *text = [NSString stringWithFormat:@"%d", i];
                    self.outletLabel1.text = text;
                   // printf("b%d
    ",i);
                });
                
            }
            
        });
        
        
        //因为 demo queue 是串行调度队列,所以等上面那个block执行完,下面这个block才会开始
        dispatch_async(queue, ^(void){
            
            for (int i = 0; i < 1000; i++) {
      
                dispatch_sync(dispatch_get_main_queue(), ^(void) {
                    
                    self.outletLabel2.text = [NSString stringWithFormat:@"%d", i];
                    
                });
            }
            
    
        });
        
        
        //xxxxx_create 的object对象要对应 xxxxx_release ?
        dispatch_release(queue);
    
        //这个循环都会卡屏幕~~~
    //    for (int i = 0; i < 100000; i++) {
    //        self.outletLabel1.text = [NSString stringWithFormat:@"%d", i];
    //        printf("%d
    ", i);
    //    }
        
    }
    
                 
    -(void)test:(NSString *)data
    {
        self.outletLabel1.text = data;
    }
    
    
    
    /*
     dispatch_group 可以把一组task放到一个group里,等group里的所有task都执行完后再继续运行
     */
    - (IBAction)btnClick3:(UIButton *)sender {
        
        //重置label2的text
        self.outletLabel2.text = @"begin";
        
        //获取一个全局并发 调度队列
        dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    
        //创建一个 dispatch group
        dispatch_group_t group = dispatch_group_create();
        
        //定义 task1
        dispatch_block_t task1 = ^(void){
            
            for (int i = 0; i < 300; i++) {
                
                dispatch_sync(dispatch_get_main_queue(), ^(void){
                    
                    self.outletLabel3.text = [NSString stringWithFormat:@"%d", i];
                });
            }
    
        };
        
        //定义task2
        dispatch_block_t task2 = ^(void){
            
            for (int i = 0; i < 300; i++) {
                
                dispatch_sync(dispatch_get_main_queue(), ^(void){
                    
                    self.outletLabel4.text = [NSString stringWithFormat:@"%d", i];
                });
            }
            
        };
        
        //把task1关联到 queue 和group
        dispatch_group_async(group, queue, task1);
        
        //把task2关联到 queue和group
        dispatch_group_async(group, queue, task2);
        
        
        //等group里的task都执行完后执行notify方法里的内容,相当于把wait方法及之后要执行的代码合到一起了
        dispatch_group_notify(group, dispatch_get_main_queue(), ^(void){
            
            self.outletLabel2.text = @"done!";
            
        });
        
        //XXX_create创建,就需要对应的 XXX_release()
        dispatch_release(group);
    }
    
    
    
    /*
     dispatch source
     */
    - (IBAction)btnClick:(UIButton *)sender {
    }
    
    
    - (void)dealloc {
        [_outletLabel1 release];
        [_outletLabel2 release];
        [_outletLabel3 release];
        [_outletLabel4 release];
        [super dealloc];
    }
    @end
  • 相关阅读:
    顺序队列的模板
    链式队列模板
    链式栈模板
    栈应用hanoi
    判断出栈顺序
    用栈实现四则运算
    两栈共享问题
    The Preliminary Contest for ICPC Asia Nanjing 2019
    Educational Codeforces Round 71 (Rated for Div. 2)
    HDU6583:Typewriter(dp+后缀自动机)
  • 原文地址:https://www.cnblogs.com/taintain1984/p/3709605.html
Copyright © 2011-2022 走看看