skynet实践(9)-随机数重复问题
最近在使用skynet的过程中,遇到需要为玩家的每次请求产生一个随机序列的场景。简化如下:
main.lua中每隔1S便发出一次随机数请求:
local skynet = require "skynet" skynet.start(function()
skynet.error("Server start")
rand = skynet.newservice("testrand")
skynet.sleep()
local i =
while i < 1 do
i = i +
skynet.send(rand, "lua", "rand")
skynet.sleep()
end
end)
testrand.lua:
local skynet = require "skynet" skynet.start(function()
skynet.dispatch("lua", function(session, address, cmd, ...)
print(math.random())
end)
end)
开发时使用的是skynet-mingw版本,测试结果如下:
0.001251220703125
0.001251220703125
0.001251220703125
0.001251220703125
0.56356811523438
0.19329833984375
0.56356811523438
0.56356811523438
0.19329833984375
0.001251220703125
可以看到,出现了很多重复的随机数,失去了随机的效果。经测试发现,如果在main.lua中不再sleep,而是连续发出随机数请求,那么生成的随机数便不会重复了。由前面对skynet的分析大家已经了解到,skynet服务在处理消息时,不同的消息可能是由不同的工作线程处理的。然后间隔请求和连续请求唯一的区别是目标服务testrand在处理消息时,间隔请求被不同线程处理的几率比较大,而连续请求被不同线程处理的几率比较小。记得之前的分析么,工作线程拿到目标的message-queue后,是会连续处理一部分消息的,处理完之后如果没事儿会休息一会儿。
既然如此,那么就在配置中将工作线程数目thread配置为1,测试结果如下:
0.00125122070312
0.56356811523438
0.19329833984375
0.8087158203125
0.58499145507812
0.4798583984375
0.35028076171875
0.89593505859375
0.82281494140625
0.74658203125
可以看到没有重复了,验证了我们的想法。而实际中我们又发现,多个工作线程时在linux上是不会出现重复的,测试结果如下:
0.84018771676347
0.39438292663544
0.78309922339395
0.79844003310427
0.91164735751227
0.19755136920139
0.33522275555879
0.76822959445417
0.27777471067384
0.55396995553747
这个又是什么原因呢?自然得从平台的差异上去查了。我们调用的是math.random()函数,它最终调用的是rand()函数,查阅文档后我们了解到,它在linux和windows平台上是有很大区别的。在linux平台上,rand()函数不是线程安全的,它隐藏了一个全局状态,每次调用都会修改这个全局状态。所以这里你会发现间隔调用时虽然可能由不同的线程执行,但是产生的随机数却是不同的。windows平台则不然,相关的状态是储存在线程的数据结构体中的,因为我们这里没有设置随机数种子,不同线程都是以默认随机数种子开始,于是出现了不同线程的随机数序列相同的情况。
skynet实践(9)-随机数重复问题的更多相关文章
- C# Random循环生成随机数重复问题解决方案
C# Random循环生成随机数重复问题解决方案1.当我们通过Random生成随机数时,习惯的写法如下: int a=new Random().Next(0,100); 然后生成一个数据数没有任何问题 ...
- iOS 生成随机数 重复 不重复
//编程的时候,有三条任选执行路径,都会显示一些图片,比如路径1显示的图片是一个人,路径2显示的是两个人,路径3显示任意人数的图片,要求每次进入该页面都不能重复初始的那张图片. 于是我想到了 运用随机 ...
- net Random 随机数重复的问题
在实际项目中不仅需要随机产生密码字符串,还要一次生成多个.我把生成随机字符串的方法放到for循环中,问题出现了. 生成的字符串,会重复. 经过多方查证,原因在代码. //使用与系统时间相关的种子 Ra ...
- C# 生成随机数重复问题
今天做测试,在一个循环里面给实体属性赋随机值,然后生成一个实体集合,突然发现生成的实体集合中的所有实体相应属性值都是一样的,调试时却又发现值并不是重复的,度娘以后发现了问题——Random类是一个产生 ...
- 并发编程:c++11 多线程中随机数重复问题
srand(time(NULL)); 是我们熟悉的c++随机函数,用时间做种子.但由于在多线程环境下若想在子线程中随机出不同的随机数则需随机种子的不同.但time以秒计算,略显不足,故参考这篇文章解决 ...
- skynet实践(8)-接入websocket
我从开源项目(https://github.com/lipp/lua-websockets,这里我们简称LWS)中抽出了websocket的部分处理,步骤如下: 1)首先是解决LWS的几个依赖问题.L ...
- C#生成不重复随机数的方法
在使用Random类生成随机数时,我们可能会碰到生成随机数重复的问题. 比如我们要生成6位数字验证码,虽然也是使用Random,但是可能出现111111,999999这样的情况. 这是因为在实例化Ra ...
- java产生不重复的随机数
/** *产生9位不同的随机数 */ private String getRandomString(){ StringBuffer sb = new StringBuffer(); for(int i ...
- JavaScript 随机数
JavaScript内置函数random(seed)可以产生[0,1)之间的随机数,若想要生成其它范围的随机数该如何做呢? 生成任意范围的随机数 //生成[100,120)之间的随机数 Math.fl ...
随机推荐
- .net 添加web引用和添加服务引用有什么区别?
添加web引用和添加服务引用有什么区别, Add Service References 和 Add Web References 有啥区别? 参考 http://social.microsoft.co ...
- spring学习六----------Bean的配置之Aware接口
© 版权声明:本文为博主原创文章,转载请注明出处 Aware Spring提供了一些以Aware结尾的接口,实现了Aware接口的bean在被初始化后,可以获取相应的资源 通过Aware接口,可以对S ...
- android开发系列之视频断点续传
今天在这篇博客里面,我想说说自己在这几天遇到的一个棘手的问题,就是视频断点续传的问题.其实这在我们开发中是一个很常见的应用场景,比如视频.音频.pdf等相关的文档.如果之前没有接触过的话,你也许会被这 ...
- 树莓派 CPU & 主板 温度
CPU cat /sys/class/thermal/thermal_zone0/temp | awk '{print $1/1000}' 主板 /opt/vc/bin/vcgencmd measur ...
- 【C/C++】高亮C++中函数的重写——函数名相同?参数列表相同?返回值相同?
C++的重载给人留下了非常深刻的影响,原因是重载的条件很值得注意:函数名相同,参数列表不相同的两个函数构成重载函数,而无关乎二者的返回值. 但是C++中的函数重写又是另一码事.标准规定:只要函数名相同 ...
- zookeeper参数的详解
安装和配置详解 本文介绍的 Zookeeper 是以 3.2.2 这个稳定版本为基础,最新的版本可以通过官网 http://hadoop.apache.org/zookeeper/来获取,Zookee ...
- Dubbo--简单介绍
Dubbo是阿里巴巴公司开源的一个高性能优秀的服务框架,使得应用可通过高性能的 RPC 实现服务的输出和输入功能,能够和Spring框架无缝集成.Dubbo致力于提供高性能和透明化的RPC远程服务调用 ...
- HTML5,不仅仅是看上去非常美(第二弹:打造最美3D机房)
前言 近期项目开发任务告一段落,刚好有时间整理这大半年的一些成果.使用html5时间还不久,对js的认识还不够深入.没办法,曾经一直搞java,对js的一些语言特性和概念一时还转换只是来. 上一篇第一 ...
- ch.poweredge.ntlmv2-auth
<dependency> <groupId>ch.poweredge.ntlmv2-auth</groupId> <artifactId>ntlmv2- ...
- 【BZOJ4653】[Noi2016]区间 双指针法+线段树
[BZOJ4653][Noi2016]区间 Description 在数轴上有 n个闭区间 [l1,r1],[l2,r2],...,[ln,rn].现在要从中选出 m 个区间,使得这 m个区间共同包含 ...