多线程

作者: zcApple | 来源:发表于2017-03-21 17:04 被阅读4次
    • 一个运行中的程序理解为一个进程,进程下面用于执行任务的通道理解为线程,一个进程下面可以有多个线程同时执行不同的任务。
    • 单个线程中任务的执行是串行的,同一时间一个线程只能进行一个任务。
      实际上CPU在特定时刻只能处理一条线程,CPU在多个线程之间快速的调度,造成一种多个线程同时执行的假象。所以多线程会大量占用CPU资源。
      程序运行时默认创建的线程称为主线程,也称为UI线程,用于UI界面的刷新、响应。耗时操作一般放在子线程执行。
    • 线程创建后进入就绪状态等待CPU调用,分配的任务执行完毕或强制退出时销毁。也可以使其进入休眠状态。
    NSThread
    // 创建并启动线程
    // 方式一:
    NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(selector) object:nil];
    [thread start];
    // 方法二:
    [NSThread detachNewThreadSelector:@selector(selector) toTarget:self withObject:nil];
    // 方法三:
    [self performSelectorInBackground:@selector(selector) withObject:nil];
    
    
    GCD
    • 任务:需要执行的操作
    • 队列:用来存放任务,分为并发队列(同时执行)和串行队列(顺序执行)
    // 创建队列  参数一:队列名  参数二:队列类型  
    dispatch_queue_t queue = dispatch_queue_create(<#const char * _Nullable label#>, <#dispatch_queue_attr_t  _Nullable attr#>)
    // 获得全局并发队列    参数一:队列优先级  参数二:待定参数 传0
    dispatch_queue_t queue = dispatch_get_global_queue(<#long identifier#>, <#unsigned long flags#>)
    // 获取主队列 队列里的任务都在主线程执行
    dispatch_queue_t queue = dispatch_get_main_queue()
    
    // 同步执行方式    在当前线程中执行任务   是即刻执行的 参数一:队列     参数二:任务      
    dispatch_sync(<#dispatch_queue_t  _Nonnull queue#>, <#^(void)block#>)
    // 异步执行方式   一般开启新的线程执行任务
    dispatch_async(<#dispatch_queue_t  _Nonnull queue#>, <#^(void)block#>)
    // 分步执行     先执行barrier之前的再执行barrier再执行barrier之后的 全局的并发队列里执行无效
    dispatch_barrier_async(<#dispatch_queue_t  _Nonnull queue#>, <#^(void)block#>)
    // 延时执行   (延迟5.0秒执行)
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
            
    });
    // 一次性代码执行 程序运行过程中只调用一次
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
          //   一次性代码
    });
    // 快速遍历执行 要在并发队列中执行  参数一:数组的个数  参数二:并发队列 参数三:元素对应的index
    dispatch_apply(10, queue, ^(size_t index) {
            
    });
    
    • 队列组
    // 添加任务到队列组 参数一:队列组  参数二:队列  参数三:任务
    dispatch_group_async(<#dispatch_group_t  _Nonnull group#>, <#dispatch_queue_t  _Nonnull queue#>, <#^(void)block#>)
    // 队列组中的任务都执行完了 会调用下面的方法
    dispatch_group_notify(<#dispatch_group_t  _Nonnull group#>, <#dispatch_queue_t  _Nonnull queue#>, <#^(void)block#>)
    
    线程同步
    • 考虑到可能有多个线程同时访问一个文件产生安全隐患,引入互斥锁对文件进行加锁。
    @property (nonatomic, strong) NSObject  *lock;  // 锁对象 由于需要记录锁的状态 所以锁对象应该始终是一个
    @synchronized (self.lock) {
            // 访问 修改
    }
    
    线程间通信
    // 调用主线程执行相关方法 第三个参数理解为是否要等到主线程执行完了selector才执行下面的代码
    [self performSelectorOnMainThread:@selector(selector) withObject:nil waitUntilDone:YES];
    // 在特定线程调用selector
    [self performSelector:@selector(selector) onThread:[NSThread mainThread] withObject:nil waitUntilDone:NO];
    
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
            // 耗时操作
            dispatch_async(dispatch_get_main_queue(), ^{
                // 回到主线程刷新界面
            });
    });
    

    相关文章

      网友评论

          本文标题:多线程

          本文链接:https://www.haomeiwen.com/subject/kxilgttx.html