Linux中的各种锁及其基本原理
0.概述
Linux系统的并行性特征
互斥和同步机制
Linux中常用锁的基本特性
互斥锁和条件变量
1.Linux的并行性特征
2.同步和互斥机制
基本概念
同步与互斥机制是用于控制多个任务对某些特定资源的访问策略
同步是控制多个任务按照一定的规则或顺序访问某些共享资源
互斥是控制某些共享资源在任意时刻只能允许规定数量的任务访问
角色分类
不可独占的共享资源
多个使用者
调度者
重要术语
竞争冒险(race hazard)或竞态条件(race condition)
临界区
3.Linux中常用的锁
锁的所有权问题 谁加锁 谁解锁 解铃还须系铃人
锁的作用就是对临界区资源的读写操作的安全限制
锁是否可以被多个使用者占用(互不影响的使用者对资源的占用)
占用资源的加锁者的释放问题 (锁持有的超时问题)
等待资源的待加锁者的等待问题(如何通知到其他等着资源的使用者)
多个临界区资源锁的循环问题(死锁场景)
自旋锁spinlock
互斥锁mutex
读写锁rwlock
RCU锁
可重入锁和不可重入锁
递归锁recursive mutex 可重入锁(reentrant mutex)
非递归锁non-recursive mutex 不可重入锁(non-reentrant mutex)
MutexLock mutex;
void testa()
{
mutex.lock();
do_sth();
mutex.unlock();
}
void testb()
{
mutex.lock();
testa();
mutex.unlock();
}
条件变量condition variables
#include <stdio.h>
#include <pthread.h>
#define MAX 5
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t notfull = PTHREAD_COND_INITIALIZER; //是否队满
pthread_cond_t notempty = PTHREAD_COND_INITIALIZER; //是否队空
int top = 0;
int bottom = 0;
void* produce(void* arg)
{
int i;
for ( i = 0; i < MAX*2; i++)
{
pthread_mutex_lock(&mutex);
while ((top+1)%MAX == bottom)
{
printf("full! producer is waiting\n");
//等待队不满
pthread_cond_wait(notfull, &mutex);
}
top = (top+1) % MAX;
//发出队非空的消息
pthread_cond_signal(notempty);
pthread_mutex_unlock(&mutex);
}
return (void*)1;
}
void* consume(void* arg)
{
int i;
for ( i = 0; i < MAX*2; i++)
{
pthread_mutex_lock(&mutex);
while ( top%MAX == bottom)
{
printf("empty! consumer is waiting\n");
//等待队不空
pthread_cond_wait(notempty, &mutex);
}
bottom = (bottom+1) % MAX;
//发出队不满的消息
pthread_cond_signal(notfull);
pthread_mutex_unlock(&mutex);
}
return (void*)2;
}
int main(int argc, char *argv[])
{
pthread_t thid1;
pthread_t thid2;
pthread_t thid3;
pthread_t thid4;
int ret1;
int ret2;
int ret3;
int ret4;
pthread_create(&thid1, NULL, produce, NULL);
pthread_create(&thid2, NULL, consume, NULL);
pthread_create(&thid3, NULL, produce, NULL);
pthread_create(&thid4, NULL, consume, NULL);
pthread_join(thid1, (void**)&ret1);
pthread_join(thid2, (void**)&ret2);
pthread_join(thid3, (void**)&ret3);
pthread_join(thid4, (void**)&ret4);
return 0;
}
4.参考资料
https://www.xuebuyuan.com/3255731.html
https://www.cnblogs.com/bigberg/p/7910024.html
http://blog.chinaunix.net/uid-26983585-id-3316794.html
https://blog.csdn.net/qq_15437629/article/details/79116590