锁

lock

分布式锁

起因 之前遇到一些场景,使用了分布式锁,目前来做一个总结 redis 1. 单点redis 单点redis场景,主要容易存在单点故障。(分布式高可用的手段:1.单点故障转移 2.数据冗余) // 获取锁 SET key value NX PX xmilliseconds // 删除锁 if redis.call("get", KEYS[1]) == ARGS[1] then return redis.call("del", KEYS[1]) else return 0 end 设置key值,需要设置一下随机value,避免锁被其他竞争者删除 设置过期时间,避免客户端崩溃之后,

By chainhelen

锁

关于锁的总结(三)信号量

难点 个人感觉信号量主要难在应用场景上; 同等对比,互斥量主要用来上锁,条件变量来优化多任务等待 其中互斥量正常场景下,都应该(最好都是遵从这样方式)保持上锁、解锁是同一个task; 在《评论迁移》里面,分布式锁redis的set NX 过程中,参数是key、requireId、expiration,其中requireId(多task环境下唯一ID)就是为了保证上锁、解锁是同一个task 综合来看,好像不需要信号量这类东西的存在 《UNIX 网络编程 卷2:进程间通信》 一书上讲了互斥量、信号量、条件变量的区别 (1)互斥锁必须总是由给它上锁的的线程(任务)解锁,信号量的挂出却不必由执行过它的等待操作的同一线程执行。(这是个特性,实际测试中go语言中的互斥量其实是可以的)。 (2)互斥锁要么被锁住,要么被解开(二值状态,类似于二值信号量)。 (3)既然信号量有一个与之关联的状态(它的计数值),那么信号量挂出操作总是被记住。然后 PV操作

By chainhelen

锁

关于锁的总结(二)条件变量

条件变量 互斥器用于互斥,条件变量用于等待 如果上例子中消费者和生产者同时并发,那么需要消费者需要轮询(polling)或者轮转(spinning) 查询buf状态,看是否满足消费条件 void comsume_wait(int i) { for( ; ; ) { pthread_mutex_lock(&shared.mutex); if (i < shared.sum) { pthread_mutex_unlock(&shared.mutex); return; } pthread_mutex_unlock(&shared.mutex); } } void *comsume(void *arg) { (void) arg; for (int i = 0;

By chainhelen

互斥量

关于锁的总结(一)互斥量

锁 我们语境下的锁是一种同步机制,用于计算机在多任务环境下访问公共资源达到互斥作用。 临界资源 临界资源(Critical Resource)是一次仅允许一个进程(任务)使用的共享资源 临界区 每个进程(任务)中访问临界资源的代码块。每次只允许一个进程进入临界区(Critical Section) 互斥量 互斥量(mutex),用于保护临界区的。下面举个例子,三个task,其中两个生产者,一个消费者 以下代码有如下假定: 1. 生产者在shared.buf[i]生成出数据 i 2. 生产者竞争(race)生产,直到所有buf区域都有数据,并此时停止生成 3. 消费者在整个buf全有数据后才开始消费 #include <stdio.h> #include <pthread.h>

By chainhelen