一、原子操作
二、死锁
造成死锁的原因:
- 自己锁自己
for(int i=0;i<MAX;++i){
//加锁
pthread_mutex_lock(&mutex);
pthread_mutex_lock(&mutex);//自己锁自己
int cur=number;
cur++;
number=cur;
printf("Thread A,id = %lu, number = %d\n",pthread_self(),number);
//解锁
pthread_mutex_unlock(&mutex);
usleep(10);
}
操作完成之后,一定要解锁。
三、读写锁
1. 读写锁是几把锁?
(1)一把锁
(2)pthread_rwlock_t lock;
2. 读写锁的类型:
(1)读锁 - 对内存做读操作
(2)写锁 - 对内存做写操作
3. 读写锁的特性:
(1)线程A加读锁成功,又来了三个线程,做读操作,可以加锁成功【读共享 - 并行处理】
(2)线程A加写锁成功,又来了三个线程,做读操作,三个线程阻塞 【写独占 】
(3)线程A加读锁成功,又来了B线程加写锁阻塞,又来了C线程加读锁阻塞【读写不能同时;写的优先级高(写锁都阻塞了那么之后的读锁肯定阻塞)】
4. 读写锁场景练习
- 线程A加写锁成功,线程B请求读锁
线程B阻塞 - 线程A持有读锁,线程B请求写锁
线程B阻塞 - 线程A持有读锁,线程B请求读锁
线程B加锁成功 - 线程A持有读锁,然后线程B请求写锁,然后线程C请求读锁
B阻塞,C阻塞 - 写的优先级高
A解锁,B线程加写锁成功
B解锁,C加读锁成功 - 线程A持有写锁,然后线程B请求读锁,然后线程C请求写锁
BC阻塞
A解锁,C加写锁成功,B继续阻塞
C解锁,B加读锁
5、读写锁的使用场景
-
互斥锁 - 读写串行
-
读写锁:
读:并行
写:串行 -
程序中的读操作>>写操作的时候
6、主要操作函数
- 初始化读写锁
pthread_rwlock_init(
pthread_rwlock_t *restrict rwlock,
const pthread_rwlockattr_t *restrict attr
);
- 销毁读写锁
pthread_rwlock_destroy(pthread_rwlock_t *rwlock);
- 加读锁
pthread_rwlock_rdlock(pthread_rwlock_t *rwlock);
阻塞:之前对这把锁加的写锁的操作
- 尝试加读锁
pthread_rwlock_trydlock(pthread_rwlock_t *rwlock);
加锁成功:0
失败:错误号
- 加写锁
pthread_rwlock_wrlock(pthread_rwlock_t *rwlocl);
上一次加锁写锁,还没有解锁的时候
上一次加读锁,没解锁
- 尝试加写锁
pthread_rwlock_trywrlock(pthread_rwlock_t *rwlock);
- 解锁
pthread_rwlock_unlock(pthread_rwlock_t *rwlock);