iOS pthread_mutex 和 pthread_cond 的应用
mutex 叫互斥锁,等待锁的线程会处于休眠状态
我们现在有个需求,存储东西和取东西,我们的需求是,但是在取东西之前要先存东西,就算两个任务同时进行,取得任务也要等存储完事才可以。其实就是线程等待的需求。
- (void)testPthread{
pthread_mutexattr_t attr;
pthread_mutexattr_init(&attr);
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
pthread_mutex_init(&(_mutex), &attr);
pthread_cond_init(&_cond, NULL);
[[[NSThread alloc] initWithTarget:self selector:@selector(delete) object:nil] start];
[[[NSThread alloc] initWithTarget:self selector:@selector(save) object:nil] start];
}
- (void)save{
pthread_mutex_lock(&_mutex);
NSLog(@"save");
pthread_cond_signal(&_cond);
pthread_mutex_unlock(&_mutex);
}
- (void)delete{
pthread_mutex_lock(&_mutex);
pthread_cond_wait(&_cond, &_mutex);
NSLog(@"delete");
pthread_mutex_unlock(&_mutex);
}
上面的代码首先创建了互斥锁和条件,我们看下面的 save 和delete方法,我们同时加了锁,是为了两个操作互斥,我们在取得操作里面加了一个条件,当我们取得时候,需要先条件等待一下,这时候我们的线程开始睡眠,这时候会解开我们的锁,当我们delete里面解开了锁,那么,我们的save就会收到锁的打开通知,就会继续往下走,然后打印save,这时候执行条件锁的signal操作,也就是唤醒操作,这句话会唤醒我们刚才睡眠的线程,然我们的刚才的线程继续往下走,这时候,我们 刚才 休眠在这里 pthread_cond_wait(&_cond, &_mutex);,就被唤醒了,就开始打印 delete,然后开始解锁,我们的save操作也开始解锁,signal 唤醒 cond 之后,虽然唤醒了线程,但是锁还是被save持有,虽然通知到delete了,但是delete这时候还没办法拿到所,需要save执行到unlock之后,把锁放开,delete才能继续向下执行,如果把unlock放在前面,signal放在unlock后面啊,那么signal发出信号之后,delete 就会立刻解锁,向下执行。
NSLock 其实就是对 pthread_mutex 的封装, NSCondition 其实就是对 pthread_mutex 和 pthread_cond 的封装。
互斥锁和自旋锁的比较
1. 一般线程等待时间比较短,不需要休眠,使用自旋锁性能好点
2. 加锁的代码经常被调用,但竞争情况很少发生的时候,用自旋锁好点
3. CPU 资源不紧张,可以考虑用自旋锁,因为自旋锁占用 cpu 资源
1. 线程等待锁的时间比较长,用互斥锁好点
2. 有I/O操作,用互斥锁好,因为占用CPU资源比较多,所以不要用自旋锁。
3. 代码比较复杂,比较耗时,用互斥锁好点。
网友评论