但各个系统的系统时间并不完全相同时,基本信号量就会出现问题:系统时间较慢的系统,将能够偷走系统时钟快的系统的信号量,导致信号量变得不公平。以下方法,只要系统间时间相差不到1秒,就不会出现信号量被偷或提早过期。

1、为信号量添加一个计数器器和一个有序集合。

2、其中计数器通过持续地执行自增操作,创建出一个类似于计时器的机制,确保最先对计数器执行自增操作的客户端最早获得信号量,将计数器的自增值用作信号量的分值,存放到有序集合中。每个客户端通过在该集合中的排名,来判断是否获得信号量使用权。

3、基本信号量中   System.currentMilstime  的有序集合得以保留,用作信号量过期。

4、通过ZinterStore命令+Weights参数,将信号量的超市时间传递给新的信号量拥有者有序集合中。

5、主要过程:

  1、首先通过从超时有序集合里面移除过期元素的方式来移除超时的信号量

  2、对超时有序集合和信号量拥有者有序集合执行交集计算,并将计算结果保存到信号量拥有者有序集合里,覆盖有序集合原有的 集合数据

  3、对计数器执行自增操作,并将计数器生成的值添加到信号量拥有者有序集合里;与此同时,程序还将当前时间添加到超市有序集合里

  4、程序检查当前客户端添加的标志符在信号量拥有者有序集合中的排名是否靠前,如果是表示客户端成功获取了信号量。否则,移除信号量拥有者有序集合和超时有序集合 中该标识符。

6、尽管如下程序并不要求所有主机都拥有相同的系统时间,但各个主机在系统时间上的差距仍需要控制在一两秒之内,从而避免信号量过早释放或者太晚释放。

7、代码结构:

def acquire_fair_semaphore(conn,semname,limit,timeout=)
identifier=uuid();
czset=semname+':owner'
ctr=semname+':counter'
now=time.time()
pipeline=conn.pipeline
pipeline.zremrangebyscore(semname,'',now-timeout)
pipeline.zinterstore(czset,{czset:,semname:})
pipeline.incr(ctr) counter=pipeline.execute()[-]
pipeline.zadd(semname,identifier,now)
pipeline.zadd(czset,identifier,counter)
pipeline.zrank(czset,identifier)
if pipeline.execute()[-] > limit
return identifier //获取信号量,成功返回
//获取失败,清理无用数据
pipeline.zrem(semname,identifier)
pipeline.zrem(czset,identifier)
pipeline.execute()
return None
  

注:对于运行32位系统的Redis来说,整数计数器最大值 2的31次方减1。在大量信号量使用的情况下,约2小时就会溢出一次。最简单的解决办法:切换到64位系统中。

释放信号量

def release_fair_semaphore(conn,semname,identifier)
pipeline=conn.pipeline
pipeline.zrem(semname,identifier)
pipeline.zrem(semname:':owner',identifier)
return pipeline.execute()[]

redis-公平信号量的更多相关文章

  1. Redis计数信号量

    计数信号量是一种锁,它可以让用户限制一项资源最多能够同时被多少个进程访问,通常用于限定能够同时使用的资源数量.你可以把Redis分布式锁里面创建的锁看作是只能被一个进程访问的信号量. 计数信号量和其他 ...

  2. 基于Redis实现分布式应用限流--转

    原文地址:https://my.oschina.net/giegie/blog/1525931 摘要: 限流的目的是通过对并发访问/请求进行限速或者一个时间窗口内的的请求进行限速来保护系统,一旦达到限 ...

  3. Java多线程系列--“JUC锁”11之 Semaphore信号量的原理和示例

    概要 本章,我们对JUC包中的信号量Semaphore进行学习.内容包括:Semaphore简介Semaphore数据结构Semaphore源码分析(基于JDK1.7.0_40)Semaphore示例 ...

  4. 019-并发编程-java.util.concurrent之-Semaphore 信号量

    一.概述 Semaphore是一个计数信号量.从概念上将,Semaphore包含一组许可证.如果有需要的话,每个acquire()方法都会阻塞,直到获取一个可用的许可证.每个release()方法都会 ...

  5. 多线程学习笔记七之信号量Semaphore

    目录 简介 数据结构 示例 实现分析 构造方法 信号量的获取(公平方式) 信号量的释放(公平方式) nonfairTryAcquireShared(int acquires) 总结 简介   Sema ...

  6. 多线程编程(一)-Semaphore(信号量)的使用

    Semaphore的介绍 单词Semaphore的中文含义就是信号.信号系统的意思,此类的主要作用就是限制线程并发的数量. 举个例子,一个屋子里有10个人,但只有一个窄门可以出去,这个窄门一次最多只能 ...

  7. 深入浅出 Java Concurrency (12): 锁机制 part 7 信号量(Semaphore)

      Semaphore 是一个计数信号量.从概念上讲,信号量维护了一个许可集.如有必要,在许可可用前会阻塞每一个 acquire(),然后再获取该许可.每个 release() 添加一个许可,从而可能 ...

  8. Semphore信号量的使用

    前言:在多线程环境的同步中,我们为了让每个线程具有同步的作用,经常采用synchronize.reetrantlock等同步手段进行上锁,以便在同一时间只能有一个线程具有访问变量和读写变量的权力.然而 ...

  9. redis-分布式锁-刷新信号量

    为什么需要刷新信号量呢,因为信号量有过期时间: 为什么信号量需要过期时间呢,因为需要利用超时特性,解决分布式锁存在的一些固有缺陷. 而对于类似流式API来说,一般10秒的过期时间是远远不够的.因此我们 ...

  10. 多线程编程-- part 9 信号量:Semaphore

    Semaphore简介 Semaphore是一个计数信号量,它的本质是一个"共享锁". 信号量维护了一个信号量许可集.线程可以通过调用acquire()来获取信号量的许可:当信号量 ...

随机推荐

  1. 大转盘(CocosCreator)

    推荐阅读:  我的CSDN  我的博客园  QQ群:704621321 1.在场景中搭建大转盘场景,假设 奖项有n项,对应的每项旋转角度如下: 第几项 需要旋转的角度 0 360/n/2 1 360/ ...

  2. egret之纹理填充模式(上下填充)

    首先,我们准备两张图片,一张作为背景“瓶子”,一张作位填充物“饮料”. 在皮肤里我们设置右边图片的填充模式为“repeat”,修改Y的缩放为:-1.,调整图片位置使之与地图重合,如下: 现在,我们可以 ...

  3. 单页面应用的History路由模式express后端中间件配合

    这篇文章主要分享一下通过HTML5的history API的时候,使用NodeJS后端应该如何配置,来避免产生404的问题,这里是使用的express的框架,主要是通过connect-history- ...

  4. 用java实现取1-100之间的99个不重复的随机数 然后输出没有被取出的数字

    package cn.kgc.springtest2.demo1.dao; import java.util.BitSet; /** * @author * @create 2019-08-02 17 ...

  5. 上海学生事务中心&新华路派出所的位置

    上海学生事务中心: 地址:冠生园路401号    工作时间:9:00-17:00    电话:021-64829191 新华路派出所: 地址:新华路590弄21号    工作时间:周一至周六 9:00 ...

  6. P1251 餐巾计划问题 费用流

    https://www.luogu.org/problemnew/show/P1251 题意 有一家酒店,酒店每天需要ri张桌布,桌布可以现买,p元.可以通过快洗店,等m天,f元.可以通过慢洗店,等n ...

  7. 1026-windy数+数位DP+记忆化搜索

    1026: [SCOI2009]windy数 题意:数位DP模板题: 目前只理解了记忆化搜索,就想练练手, ------给递推写法留一个位子 ------ 注意这道题要判断前导0的情况,1 )可以加一 ...

  8. CodeForces 669 E Little Artem and Time Machine CDQ分治

    题目传送门 题意:现在有3种操作, 1 t x 在t秒往multiset里面插入一个x 2 t x 在t秒从multiset里面删除一个x 3 t x 在t秒查询multiset里面有多少x 事情是按 ...

  9. 牛客小白月赛4 J 强迫症 思维

    链接:https://www.nowcoder.com/acm/contest/134/J来源:牛客网 题目描述 铁子最近犯上了强迫症,他总是想要把一个序列里的元素变得两两不同,而他每次可以执行一个这 ...

  10. 天梯杯 PAT L2-001. 紧急救援 最短路变形

    作为一个城市的应急救援队伍的负责人,你有一张特殊的全国地图.在地图上显示有多个分散的城市和一些连接城市的快速道路.每个城市的救援队数量和每一条连接两个城市的快速道路长度都标在地图上.当其他城市有紧急求 ...