互斥锁的概念,与部分接口

何为互斥

一种对共享数据的保护,防止多线程同时访问共享资源的时,数据混乱的问题。在互斥期间,保证执行流由并行改为串行。任何时刻,互斥保证有且只有一个执行流进入临界区,访问临界资源,通常对临界资源起保护作用 原子性(后面讨论如何实现):不会被任何调度机制打断的操作(有歧义,会被打断,但是无法影响对数据的访问),该操作只有两态,要么完成,要么未完成

互斥锁的概念,与部分接口_第1张图片

加锁后,到解锁过程中,只允许一条执行流访问该区块代码,这就是我们所谓的原子性

互斥锁接口

锁类型名

pthread_mutex_t mtx //定义一个叫做mtx的锁

锁的声明方法(静/动态

//静态初始化锁
pthread_mutex_t mtx=PTHREAD_MUTEX_INITIALIZER

//动态初始化锁

int pthread_mutex_init(pthread_mutex_t * mutex, const pthread_mutexattr_t *attr);
//省略了restrict

在动态申请的初始化后,需要主动释放锁。

//对于动态申请的锁,在在最后需要手动释放锁
pthread_mutex_init(&mtx);
//。。。。

//不用该锁后
pthread_mutex_destroy(&mtx);

阻塞加锁int pthread_mutex_lock

int pthread_mutex_lock (pthread_mutex_t *__mutex);

如果该锁已经被其他执行流占用,或在竞争的时没有争到锁,线程将阻塞,等待占用锁的线程释放锁后再去争夺锁的使用。

非阻塞加锁int pthread_mutex_trylock

int pthread_mutex_trylock (pthread_mutex_t *__mutex)

尝试占用锁,在未占用锁时,不会进入阻塞状态,返回错误码后继续执行后续代码。可以根据是否返回0做if判断。

释放锁int pthread_mutex_unlock

int pthread_mutex_unlock (pthread_mutex_t *__mutex)

释放__mutex锁资源。

互斥锁底层逻辑

锁其实也是共享资源,也是被多个执行流所访问,那么怎么保护加锁和释放锁的原子操作

利用汇编中的指令:swap或exchange,这两条指令是将两个数据交换的,这种交换在汇编中只有一条语句,要么交换完成要么不交换,保证原子操作。

看看加锁的伪代码

互斥锁的概念,与部分接口_第2张图片

先来看看lock加锁代码的逻辑。

互斥锁的概念,与部分接口_第3张图片

 首先内存中锁保存了个资源1,线程1、2的上下文al都是被初始化为0的。

线程1先跑,调用lock函数,初始化al为0后交换数据 

互斥锁的概念,与部分接口_第4张图片

然后立刻被切换到线程二

互斥锁的概念,与部分接口_第5张图片

 然后线程二,走else被挂起互斥锁的概念,与部分接口_第6张图片

 切换会线程1,出if成立函数lock执行后续代码

互斥锁的概念,与部分接口_第7张图片

在这期间,线程2一直被阻塞,直到线程1调用unlock函数,重新写入mutex为1,注意,在代码书写不当时,拥有A锁的线程再去申请A锁将自我阻塞死锁情况。

你可能感兴趣的:(数据库)