oc 基础 多线程

pthread c 语言 NSthread GDC 充分利用多核 NSOperation

GCD 常用API

主队列:dispatch_get_main_queue()
  1. 专门用来在主线程上调度任务的队列
  2. 不会开始线程
  3. 如果当前主线程正在由任务执行,那么无论主队列中当前被添加了什么任务,都不会被调度
  4. 可以理解为串行队列(serial),但是它的行为并不完全像常规的串行队列
  5. 在main()函数创建之前就有主队列了
全局队列:
  1. 为了方便程序员的使用,苹果提供了全局队列:dispatch_get_global_queue(0, 0)
  2. 全局队列是一个并发队列(concurrent)
  3. 在使用多线程开发时,如果对队列没有特殊需求,在执行异步任务时,可以直接使用全局队列

dispath_sync 在当前的线程中执行任务

dispath_async 在新的线程中执行任务,不一定可以开启新的线程

并发 多个任务同时执行 串行 一个爱一个执行

主队列是一种特殊的串行队列

同步 一定是 串行执行,因为只有一个线程

只有 异步 + 并发队列 才会 并发执行任务

死锁 问题

情况 1

viewDidload { nslog (1) dispath_sync (getmainqueue, ^{ nsllog(2); }) nslog(3) }

队列的特点 排队 先进先出 FIFO

并发执行任务一 任意二 之后执行任务3

使用任务组

gispath_group_t group = dispath_group_create();

创建并发队列

diapath_queue queue = dispath_queue (CONCURRENT);

添加异步任务 使用 group 函数

dispath_group_async (group, queueu, ^{ nslog(1) }) dispath_group_async (group, queueu, ^{ nslog(2) })' // 唤醒 dispath_group_notify(group,queue, ^{ nslog(3) })

dispath_group_notify(group,queue, ^{ nslog(4) })

34 会交替执行

dispath_group_notify(group,get_main_queue, ^{ nslog(4) })

多线程的安全隐患

  1. 多个线程同时访问一块内存
  2. 引发数据错乱和

使用线程同步技术 解决问题

1 枷锁

iOS 中 有这9种锁

小心死锁问题

OSSpinkLock (高级锁)

自旋锁 一直占用资源,盲等, 不安全 可能出现 优先级反转

优先级反转 :

thread1 10ms 高 thread2 10ms 底 thread3 10ms 线程的调度 每个线程分配时间片 多线程的原理

优先级高的话 时间给的会多一点

如果 2 枷锁 , 1 如果看到2 加锁 会等待2 , 一直分配时间给 1

thread2 没有时间 可能导致不执行

{ #improt <os/lock.h> OSSpinkLock *lock = OS_Spink_init; ios10 已经过期

}

os_unfair_loack fair(公平) 低级锁, 等不到 就休眠 取代 osspinklock 加锁的线程 处于休眠状态

pthread_mutex

mutex 互斥锁 等待的或线程会休眠

{ #import <pthread.h> @property (nonatomic) pthread_mutex mutex; //静态初始化 pthread_mutex = PETHEAD_MUTEX_INITAILIZE; //初始化属性 pthread_mutext_attr_t attr; pthread_mutet_settype(&attr, PTHREAD_MUTEXT_NORMAL) { #define PTHREAD_MUTEXT_NORMAL 0 #define PTHREAD_MUTEXT_ERRORCHECK 1 #define PTHREAD_MUTEXT_RECURSIVE 2 递归锁 #define PTHREAD_MUTEXT_DEFAULT

} // 设置属性

//初始化锁

pthread_mutext_init(&mutex,attr);

// 销毁锁

pthread_mutex_destory(&att)

// 初始化条件

pthread_cond_t = condition;

pthread_cond_init(&condition)

RECURSIVE 递归所 允许同一个线程重复加锁

  • (void)test { pthread_mutext_lock(&mutext);

      [self test];
    
      pthread_mutext_unlock(&mutext);
    复制代码

    } // 删除数组中元素

    • (void)test2 {

      pthread_mutext_lock(&mutext);

      [self test];

      pthread_mutext_unlock(&mutext);

    }

    • (void)__remode { pthread_mutext_lock(&mutext);

      if (array.count == 0) { //达到条件 后让线程等待 所以是条件锁 应用场景线程 1 依赖 线程 2 ; 生产者 -- 消费者 模式 pthread_cond_wait(&cond,&mutext); }

      [array removeObjc];

      pthread_mutext_unlock(&mutext);

    }

    • (void)__add { pthread_mutext_lock(&mutext);

      [array addObjc]; // 发送 信号 结束等待 pthread_cond_signal(&cond); // 发广播,多个 wait 同时能收到 pthread_cond_broadcast(&cond);

      pthread_mutext_unlock(&mutext);

    }

}

dispath_semaphore

// 可以控制对打并发线程数量

{ 信号量的初始值 是1
diapath_semaphor_t semaphore = dispath+semaphore_create(value) // 如果信号量小于等于 0 就进入休眠等待 // 如果信号量的值大约 0 就-1 然后往下执行后面的代码 diapath_memaphore_wait(semaphor,DISPATH_TIME_FOREVER);

 // 让信号量的值 加一
 dispatch_semaphore_signal(smaphore)
 
复制代码

}

dispath_queue(SERIAL)

NSLock // 对 pthread defoult 的封装

NSRecurisiveLock // 对 pthread Recurisive 的封装

NSCondition // 对 pthread mutex 和 con 的封装

NSConditionLock 对 NSCondition 进一步的封装 可以对条件设置 值

可以设置线程之间的依赖

{ self.conditionLock = [NSCondition alloc]initWidthCondition:1];

 - (void)test {
     [NSthread alloc] initWidthTarget: self selector:@selector(__one) object start];
     [NSthread alloc] initWidthTarget: self selector:@selector(__two) object start];
     [NSthread alloc] initWidthTarget: self selector:@selector(__three) object start];
     
     
     
     - (void)__one {
         [self.conditionLock lockWhenCondition:1];
         nslog(11);
         [self.conditionLock unlockWhenCondition:1];
     }
     
     - (void)__two {
         [self.conditionLock lockWhenCondition:2];
         nslog(22);
         [self.conditionLock unlockWhenCondition:3];
     }
     
     - (void)__three {
         [self.conditionLock lockWhenCondition:3];
         nslog(33);
         [self.conditionLock unlock];
     }
     
     
     
     
 }
     
复制代码

}

@synchronized // 相当于对 pthread mutex 递归锁的封装

{ - (void)test{ @synchronized ([self class]) { self class 的唯一性 成为 同一把锁 的关键 } @synchronized (self) { nslog(11) } }

}


IO 操作 多读 单写

  1. 从文件中 读取内容

  2. 往文件中写入内容

要求

同一时间 只能有一个线程写的操作 同一时间 允许有多个读的操作 同一时间 不允许既有写的操作,又有读的操作

方案一 pthread_rwlock 读写锁

方案二 dispath_barrier_async : 异步栅栏函数

pthread_rwlock


//初始化锁
    pthread_rwlock_t lock
    pthread_rwlock_init(&lock,BULL)
    // 读取加锁
    pthread_rwlock_rdlock(&lock)
    //写加锁
    pthread_rwlock_wrlock(&lock)
    //解锁
    pthread_rwlock_unlock(&lock)
    //销毁
    pthread_rwlock_destory

复制代码

猜你喜欢

转载自juejin.im/post/7110152877619806244
今日推荐