在秒杀,抽奖等活动中,避免商品超卖甚至库存变负数的问题。
锁是用来做并发最简单的方式,其代价也是最高的
通过update
返回值来判断库存:
update set number=number-1 where number > 0
update set number=if(number>0, number-1, number)
if (flock($fp, LOCK_EX)) { flock($fp, LOCK_UN); }
把奖品塞到队列里, 按照FIFO
顺序执行
Beanstalk is a simple, fast work queue.
redis的数据类list可以用来实现队列, 左边压入lpush
, 右边弹出rpop
。
Simple Queue Service over Memcache
微博转发得奖就常常使用这种算法,即根据转发次数来决定奖品归属,透明而且具有激励性。
“几”=(抽奖人数/奖品数)*第几个奖品+特定数, 如果是实时抽奖, 则需要预估抽奖人数和奖品数。
依赖开奖日收盘时的上证指数
& 收盘时的深证成指
这种不可控的物理随机数A,算法约等为:
“几”=不可空物理随机数%抽奖人数 + 特定数*第几个奖品
概率抽奖可以理解为一个转盘,指针最终都会指向某个扇形区域, 触发概率为100%
即1
指针最终都会指向扇形的弧上的某一点,因而可以把转盘展开成一条长为周长的线段,命名为TP线(Total probability-Line)。在TP线上随机任取一点。随机取出的这一点出自哪一条线段,则此线段对应的项目被抽中。
项目 | 概率 |
---|---|
A | 0.3 |
B | 0.2 |
C | 0.4 |
将项目A, B, C的概率进行求和以作为TP线的总长。用函数random(0,1)*TP线的长度来取TP线上的点。若取得的结果在[0,0.3)时,项目A被抽中;取得的结果在[0.3,0.5)时,项目B被抽中;取得的结果在[0.6,0.9)时,项目C被抽中;
function random($prizes) { $index = null; $probabilitySum = array_sum($prizes); $rand = mt_rand(1, $probabilitySum); foreach ($prizes as $key => $probability) { if ($rand <= $probability) { $index = $key; break; } else { $rand -= $probability; } } return $index; }
function random($prizes) { $index = null; $probabilitySum = array_sum($prize); foreach ($prizes as $key => $probability) { $rand = mt_rand(1, $probabilitySum); if ($rand <= $probability) { $index = $key; break; } else { $probabilitySum -= $probability; } } return $index; }
美团网的抽奖是什么原理? 如何高效设计游戏——从抽奖模型到圆桌算法(上) 如何高效设计游戏——从抽奖模型到圆桌算法(下) 游戏命中判定:圆桌算法和程序实现 用JavaScript玩转游戏编程(一)掉宝类型概率 Darts, Dice, and Coins: Sampling from a Discrete Distribution
双11抽奖活动平台测试总结 一种高效无锁内存队列的实现 Beanstalk is a simple, fast work queue Redis 命令参考 使用 Redis 实现分布式锁
Yan Peipan 08 December 2014