Srand函数

来源:互联网 发布:南昌重点高中知乎 编辑:程序博客网 时间:2024/06/05 15:03

问题描述】
在主线程里面srand()了一次,然后在线程函数里面使用rand(),可是每个线程rand出来的数列顺序一样,而且每次运行都一样。结构如图所示:
da646bd79c1fd6f6a144dfa0.jpg
func1出来的序列是1,7,4,0,9,4,8……
func2出来的序列是1,7,4,0,9,4,8……

【讨论】
网上有人说这是因为main的seed是time,而两个线程是几乎并发开始的,它们继承了main的seed,因此输出序列相同。
【证伪】
[1]将main中的随机种子设为srand(1),其余不做改变。两个线程输出结果仍旧是1,7,4,0,9,4,8……
这说明main中的种子与线程中并无关系。
[2]为了巩固以上假设,进行一下测试:
main中srand(time),在func1和func2里面均加上语句srand(1),输出序列均为1,7,4,0,9,4,8……
main中srand(time),在func1和func2里面均加上语句srand(time),输出序列均为2,9,4,6,8,3,7……
main中srand(1),在func1和func2里面均加上语句srand(time),输出序列均为2,9,4,6,8,3,7……
main中srand(1),在func1里加上srand(1),func2里面加上srand(time),输出序列分别为1,7,4,0,9,4,8……和2,9,4,6,8,3,7……
——由此,证明了无论main中的srand是如何的,线程中的rand结果只与该线程中的srand有关。也即,多线程编程中,在每个线程里面都要srand一次。
说明:由于如果没有显式srand,系统默认为rand(1),因此在func里面用不用该语句输出都一样。当然,如果两个线程中都srand了time,由于它们并发运行,也就是说执行srand的时候它们的time相同,即种子相同,从而输出序列相同。

【问题解决】
如何做到不同线程中的数从横向上看来也不同呢?
先从rand的伪随机性说起。
我们都说rand是伪随机的,是因为它有章可循,并不是真的“随机”。它是以某个线性同余的递推公式推算出来的一些列数,当这系列数很大的时候,它们就符合正态分布。这个递推公式类似于:
y=ax+b(mod   n),其中,a、n一般是大素数,而a、b、n都是常数,因此rand的产生决定于x,而且下一个y是上一次产生的y的函数。
-----------------------------------------------------------------------
比如VC中对于rand()函数是如下实现的:
int   __cdecl   rand   (void)   
{  return(((holdrand   =   holdrand   *   214013L   +   2531011L)   >>   16)   &   0x7fff);   }
-------------------------------------------------------------------------
而srand()的函数是如下实现的:
void __cdecl srand (unsigned int seed)
{
  #ifdef _MT 
    _getptd()->_holdrand = (unsigned long)seed;  
  #else /* _MT */
   holdrand = (long)seed;
  #endif /* _MT */
}
-------------------------------------------------------------------------
递推公式意味着,确定的输入产生确定的输出,而且顺序是不变的。因此,当我们设置srand()的时候,相当于设置了递推公式的数列起点,从x开始计算y。因此,srand的种子相同相当于起点相同,数列相同也就可以理解了。
那么,如果要让两个数列不同,只需要srand的时候使用不同seed就可以了。可以采取以下方法:
1)在外部产生随机数,然后将该数作为参数传进线程函数设为seed。
2)将线程ID作为线程的seed。
3)使用其他可以令线程拥有不同seed的方法。
*)最好不要使用time(NULL)作为每个线程的seed,因为线程开始的time(NULL)很可能相同。

转自:http://hi.baidu.com/czlaner/blog/item/c06200097c849dc63ac76344.html

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 别人发的cdr文件打开太慢怎么办 qq红包充值话费未到账怎么办 qq飞车充值至尊皇冠不到账怎么办 微信支付金额超过单日限制怎么办 不小心在qq钱包中充错话费怎么办 衣服质量不好穿了几次就坏了怎么办 手机丢了找到手机店的人怎么办 在手机店买手机买贵了怎么办 王者荣耀好多没对的东西怎么办 用电脑玩游戏键盘不管用怎么办? 王者荣耀跨系统送皮肤领不到怎么办 电脑使用迅雷时提示缓存过高怎么办 扣扣安全中心动态密码忘记了怎么办 pu管两头固定了中间换截怎么办 自己架设的传奇不能注册帐号怎么办 天堂2第八章读取服务端错误怎么办 苹果手机王者荣耀下了不能玩怎么办 苹果手机摔了一下触屏失灵怎么办 华为机回复出厂设置帐号忘了怎么办 华为手机里突然有个pp助手怎么办 华为手机与电脑连接不上怎么办 买房交了首付贷不了款怎么办 手机买贵了实体店不肯退怎么办 在实体店里手机买贵了怎么办 红米手机开启不了安装系统怎么办? 捡个荣耀8双清后要账号怎么办 荣耀7x升级8.0后耗电快怎么办 手机提示当前为耳机播放模式怎么办 华为手机进水了显示耳机模式怎么办 苹果6s突然变成耳机模式怎么办 华为手机出现耳机标志没声音怎么办 苹果手机微信变成耳机模式怎么办 5s不能用4g网络怎么办 华为麦芒四手机系统乱了好卡怎么办 信翼路由器登录密码忘了怎么办 苹果手机电信4g信号变3g怎么办 苹果7手机4g变3g怎么办 朵唯v3逆客手机不支持计步怎么办 移动卡升级4g后网络不好怎么办 电信办宽带送的手机卡不用了怎么办 移动华为悦盒遥控器丢了怎么办