pthread c 语言 NSthread GDC 充分利用多核 NSOperation
GCD 常用API
主队列:dispatch_get_main_queue()
- 专门用来在主线程上调度任务的队列
- 不会开始线程
- 如果当前主线程正在由任务执行,那么无论主队列中当前被添加了什么任务,都不会被调度
- 可以理解为串行队列(serial),但是它的行为并不完全像常规的串行队列
- 在main()函数创建之前就有主队列了
全局队列:
- 为了方便程序员的使用,苹果提供了全局队列:dispatch_get_global_queue(0, 0)
- 全局队列是一个并发队列(concurrent)
- 在使用多线程开发时,如果对队列没有特殊需求,在执行异步任务时,可以直接使用全局队列
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 枷锁
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 操作 多读 单写
-
从文件中 读取内容
-
往文件中写入内容
要求
同一时间 只能有一个线程写的操作 同一时间 允许有多个读的操作 同一时间 不允许既有写的操作,又有读的操作
方案一 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
复制代码