基础_iOS_2022_锁
在多线程编程中,线程同步是必不可少的考虑环节。线程不同步导致的问题很难排查,甚至bug复现的都很困难。
所以在多线程编程中,应该在设计中考虑到数据同步问题,保证变量视图的一致性,避免出现不一致性情况。
为什么使用线程锁
可以用程序修改变量值时所经历的三个步骤解释这个现象:
- 从内存单元读入寄存器
- 在寄存器中对变量操作(加/减1)
- 把新值写回到内存单元
解决线程不安全
多线程程序中可能会存在数据不一致的情况,那么如何保证数据一致呢?可以考虑同一时间只有一个线程访问数据。互斥量(mutex)就是一把锁。
锁的种类
互斥锁、读写锁、条件锁、自悬锁
互斥锁:可以考虑同一时间只有一个线程访问数据。互斥量(mutex)就是一把锁
条件锁:允许线程以无竞争的方式等待特定的条件发生。条件变量是线程可用的另一种同步机制。
读写锁:允许更高的并发性
自旋锁:与互斥类似,但获取锁之前一直处于忙等阻塞状态
避免死锁
产生死锁的情况较多,如一个线程对变量a加锁后,试图对变量b加锁,另一个线程对变量b加了锁,试图对a加锁,这时两个线程都不释放锁,加不会加锁成功,造成两个线程处于死锁状态。
死锁的四个条件
死锁产生的四个必要条件
1、互斥使用,即当资源被一个线程使用(占有)时,别的线程不能使用
2、不可抢占,资源请求者不能强制从资源占有者手中夺取资源,资源只能由资源占有者主动释放。
3、请求和保持,即当资源请求者在请求其他的资源的同时保持对原有资源的占有。
4、循环等待,即存在一个等待队列:P1占有P2的资源,P2占有P3的资源,P3占有P1的资源。这样就形成了一个等待环路。
-
iOS
pthread_mutex_t(互斥)
声明
pthread_mutex_t _lock; // recursive lock
初始化
pthread_mutexattr_t attr;//互斥锁 pthread_mutexattr_init (&attr);//初始化互斥锁 pthread_mutexattr_settype (&attr, PTHREAD_MUTEX_RECURSIVE); pthread_mutex_init (&_lock, &attr); pthread_mutexattr_destroy (&attr);
加解锁
pthread_mutex_lock(&_lock); //do something pthread_mutex_unlock(&_lock);
销毁
pthread_mutex_destroy(&_lock);