3.2.6 手把手实现分布式锁

手把手实现分布式锁
进程中的锁

1.互斥锁
2.自旋锁
3.读写锁
4.信号量
5.条件变量
6.原子变量以及内存屏障

进程间通信

1.pipe
2.FIFO
3.信号量
4.信号
5.消息队列
6.共享内存
7.socket

1.条件变量为什么与互斥锁协同
条件的判断是一个临界资源,需要互斥锁保护
2.哪些锁是自己加锁自己释放锁?哪些是自己加锁,可能由别的线程释放锁?
互斥锁,自旋锁;信号量和条件变量可能由别的线程释放锁;

pthread_mutex_lock(&mtx);

while (condition) //解决了虚假唤醒的问题
  pthread_cond_wait(&cond, &mtx);
pthread_mutex_unlock(&mtx);

pthread_mutex_lock(&mtx);
pthread_mutex_unlock(&mtx);
pthread_cond_signal(&cond);

pthread_cond_broadcast(&cond);

为什么会产生虚假唤醒(pthread_cond_wait会返回,但其实条件并不满足)问题:

1.条件变量有可能会被信号打断
信号 -1 = read errno = EINTR
2.信号劫持
3.多处理实现过程中出现的bug:signal可能会唤醒多个

分布式锁是什么类型的锁?
在分布式场景中实现互斥类型的锁
分布式:运行的节点可能在不同机器或不同网段当中,节点间通信通过socket
互斥类型:同一时刻只允许一个执行体进入临界资源
解决了什么问题?
在分布式场景中,同时只允许一个节点执行某类任务
什么场景下
分布式场景中
行为:加锁,解锁-》网络交互-》锁超时功能,由锁存储的所在节点来实现
加锁对象和解锁对象必须为同一个 -》除了因为网络异常而造成锁超时情况
分布式锁特性
1.互斥性:
锁打上标记:加锁
锁取消标记:解锁
标记:执行体的唯一标识
2.锁超时
3.可用性
3.1合理时间内得到合理的回复
3.2实现
3.2.1计算型(网关)-> 开多个备份点
3.2.2存储型 ->多个备份点/主从切换
4.容错性 一致性来解决(半数以上)
4.1 raft一致性算法
4.2 redlock

分布式锁类型
重入锁和非重入锁:允许同一个线程多次持有锁
公平锁和非公平锁
公平锁:排队
非公平锁:轮询

公平锁   互斥锁
非公平锁  自旋锁

实现重点
锁是一种资源,需要存储;同时要保证可用性,避免锁失效 ->一个进程多线程中的锁资源存储在进程中
互斥语义:将锁打标记
1.加锁对象和解锁对象必须为同一个
2.解锁时需要判断当前持有锁的对象是否是自己
加锁解锁行为是网络通信,需要锁超时->进程是资源的容器,线程是执行的单元
怎么获知持有锁对象的释放锁行为?
主动探寻->非公平锁
被动通知
是否允许同一持锁对象多次加锁?重入锁,非重入锁

文章参考于<零声教育>的C/C++linux服务期高级架构系统教程学习:https://ke.qq.com/course/417774?flowToken=1020253

你可能感兴趣的:(零声教育,分布式)