精华内容
下载资源
问答
  • rand

    2021-01-18 21:40:56
    关于rand( )问题关于rand()问题题目:编写产生1000个1到10范围的随机数的程序,不必保存或打印数字,仅打印每个数字产生了多少次,让程序对10个不同的种子进行计算,数字出现的次数相同吗?可以使用自定义函数或ANSI...

    关于rand( )问题

    关于rand()问题

    题目:编写产生1000个1到10范围的随机数的程序,不必保存或打印数字,仅打印每个数字产生了多少次,让程序对10个不同的种子进行

    计算,数字出现的次数相同吗?可以使用自定义函数或ANSIC中的rand()和srand(),这是一个测试特定随机发生器的随机性的方法。

    第一部分已做出了,但红色部分应该采用什么方法来做呀?搜索更多相...

    2

    热度

    random和rand

    random和rand

    rand是个伪随机数,拿当前时间做种子,获取的数是4位数,如何随机获取1到6,且1到6这6个数机会相等,random(intn)是获取[0,n)的随机数,我机器运行的时候一直提示'random':undeclaredidentifier请教高手什么原因,头文件有了我搜了下他们的用法,机器运行不了random的,也没...

    1

    热度

    php随机数rand跟mt_rand

    php随机数rand和mt_rand

    今天想写个扔骰子并统计点数概率的小程序,使用如下方法生成随机数

    for($j=0;$j<10000;$j++){

    for($i=0;$i<6;$i++){

    $tempArray[$i]=rand(1,6);

    }

    $temp=array_count_values($tempArray);

    for($i=1;$i<7;$i++){

    ...

    1

    热度

    random和rand

    已经调试过了,没有任何输出结果.

    color='#FF8000'>----------------解决方案--------------------------------------------------------

    不会吧#include#include

    void...

    1

    热度

    random和rand

    请问一下什么是野数啊我在这里看见野数不知道是什么?

    color='#FF8000'>----------------解决方案--------------------------------------------------------

    我自己乱说的,不过有野指针,就是未初始化的指针,前面的代码运行。打不出第一个数,是个不知道的...

    1

    热度

    求助:关于rand()的用法

    求助:关于rand()的用法

    前几天上课的时候老师给我们介绍了C语言中的一个rand()函数,说是可以随机产生0到1的数,但是我上机编写了一个程序,发现它并不是产生的0到1的数。我上网搜了一下,一些人说这个函数要和srand()一起使用,但是我把他们的程序编译不通过。那位要是知道就麻烦你教我一下。谢谢!搜索更多相关的解决方案:

    rand"ta...

    1

    热度

    怎么用rand()这个函数啊??????

    怎么用rand()这个函数啊??????

    怎么用rand()啊,让它产生1~100之间的数??????搜索更多相关的解决方案:

    rand"target="_blank">color="red">randcolor="red">函数

    color='#FF8000'>----------------解决方案...

    2

    热度

    还是rand()的有关问题

    还是rand()的问题SelectTOP50Rand()asshuijshu,*IntoCursorkuaijimokao_2Fromtiku_jiangsuSelectTOP50Rand(-1)asshuijshu,*IntoCursorkuaijimokao_2Fromtiku_jiangsu同样是使用的rand()函数,出来的结果,居然还不同,上面一句,每一条记录中shuijshu的值都不同...

    6553

    热度

    想知道rand()内部结构!

    想知道rand()内部结构!

    rand()函数,它产生的一个随机数,而这个随机数就是产生下一个随机数的种子,是这样的吗?

    希望同仁提供一下rand()函数的内部结构!搜索更多相关的解决方案:

    rand"target="_blank">color="red">randcolor="red">结构color="red">随机数color="red...

    1

    热度

    怎么用rand()这个函数啊??????

    怎么用rand()这个函数啊??????

    怎么用rand()啊,让它产生1~100之间的数??????搜索更多相关的解决方案:

    rand"target="_blank">color="red">randcolor="red">函数

    color='#FF8000'>----------------解决方案...

    2

    热度

    如何得出rand( )中的种子?

    如何得出rand()中的种子?

    编写产生1000个1到10范围的随机数的程序,不必保存或打印数字,仅打印每个数字产生了多少次,让程序对10个不同的种子进行

    计算,数字出现的次数相同吗?可以使用自定义函数或ANSIC中的rand()和srand(),这是一个测试特定随机发生器的随机性的方法。

    “让程序对10个不同的种子进行计算,数字出现的次数相同吗”这步怎么算呀,我怎么...

    1

    热度

    [求助]为什么A=rand();A总是等于346呢?

    [求助]为什么A=rand();A总是等于346呢?

    [求助]为什么A=rand();A总是等于346呢?搜索更多相关的解决方案:

    rand"target="_blank">color="red">rand

    color='#FF8000'>----------------解决方案------------...

    2

    热度

    [讨论]有关rand()生成数的大小..

    [讨论]有关rand()生成数的大小..

    我想生成32bits的随机数...现在想知道rand()最大能生成多少bits的随机数搜索更多相关的解决方案:

    rand"target="_blank">color="red">randcolor="red">成数

    color='#FF8000'>-------...

    2

    热度

    [求助]谁知道rand()函数的作用和用法

    [求助]谁知道rand()函数的作用和用法

    谢谢回答!!!搜索更多相关的解决方案:

    rand"target="_blank">color="red">randcolor="red">函数color="red">用法

    color='#FF8000'>----------------解决方案--------...

    1

    热度

    mysql rand()中随机的解决办法

    求一个mysqlrand()中随机的解决方法我想通过这个语句selectsp.subID,sp.subName,sp.subImagefromsubproductsp,mainproductmpwheremp.mainID=sp.mainIDandmp.mainName='$name'orderbyratedesc,timedesclimit4中找出的结果再随机显示呢!!请各位赐教...

    3

    热度

    跪:sql随机数rand()有关问题

    跪求高手指教:sql随机数rand()问题我知道随机生成0-99的语句selectcast(rand()*100asint)问题1:那如果是50-99的那该样生成呢问题2:如果我生成的随机数不满足条件需要重新生成那该怎样写呢我是这样写的while1=1beginbreak//满足条件end不知道效率高不高求高手指教color='#FF8000'>------解决方案----------------...

    5591

    热度

    [讨论]有关rand()生成数的大小..

    //-------失误,因为因为数据刷新了-------------//

    color=#000066>[此贴子已经被作者于2007-11-41:26:15编辑过]

    color='#FF8000'>----------------解决方案--------------------------------------------------------

    ...

    2

    热度

    rand()函数并不能达到真正意义上的产生随机数

    rand()函数并不能达到真正意义上的产生随机数

    rand()函数并不能达到真正意义上的产生随机数.

    我的意思是rand()产生的数是有规律可循的:由同一个种子产生的随机数是固定不变的.

    在C语言里,设置种子的函数是voidsrand(unsignedseed);.请看下面的几个例程:

    /*编译环境vc6.0*/

    #include

    ...

    1

    热度

    rand()的有关问题(虽然已结账,但还没有弄明白)

    rand()的问题(虽然已结账,但还没有弄明白)SelectTOP50Rand()asshuijshu,*IntoCursorkuaijimokao_2Fromtiku_jiangsuSelectTOP50Rand(-1)asshuijshu,*IntoCursorkuaijimokao_2Fromtiku_jiangsu同样是使用的rand()函数,出来的结果,居然还不同,上面一句,每一条记录中...

    5704

    热度

    [求助]怎样将rand()产生的随机数存入数组

    [求助]怎样将rand()产生的随机数存入数组

    怎样将rand()产生的20个随机数存入数组?并统计某个数的出现次数我是初学者.求大侠指教.搜索更多相关的解决方案:

    rand"target="_blank">color="red">randcolor="red">随机数

    color='#FF8000'>...

    1

    热度

    展开全文
  • PHP 中 rand()与mt_rand()都是用于产生一个指定范围内单独随机数的...rand()函数默认使用 libc 随机数发生器,很多老的 libc 的随机数发生器具有一些不确定和未知的特性而且效率很低;mt_rand() 则是用了 Mersenne T...

    PHP 中 rand()与mt_rand()都是用于产生一个指定范围内单独随机数的函数,如果需要产生多个不重复的随机数,请参考:PHP生成指定范围内的N个不重复的随机数。

    既然他们都是用于产生一个随机数,那么他们有什么区别呢?

    rand() 函数默认使用 libc 随机数发生器,很多老的 libc 的随机数发生器具有一些不确定和未知的特性而且效率很低;

    mt_rand() 则是用了 Mersenne Twister 中已知的特性作为随机数发生器,它产生随机数值的平均速度比 libc 提供的 rand() 快四倍。

    所以,PHP 中 mt_rand()函数是非正式用来替换rand()的。

    rand — 产生一个随机整数 (PHP 4, PHP 5, PHP 7)

    rand ( void ) : int

    rand ( int $min , int $max ) : int

    参数

    min    返回的最低值(默认:0)

    max    返回的最高值(默认:getrandmax())

    返回值   A pseudo random value between min (or 0) and max (or getrandmax(), inclusive)

    如果没有提供可选参数 min 和 max,rand() 返回 0 到 getrandmax() 之间的伪随机整数。例如想要 5 到 15(包括 5 和 15)之间的随机数,用rand(5, 15)。

    说明:在某些平台下(例如 Windows)getrandmax() 只有 32767。如果需要的范围大于 32767,那么指定 min 和 max 参数就可以生成更大的数了,或者考虑用 mt_rand() 来替代之。

    mt_rand — 生成更好的随机数    (PHP 4, PHP 5, PHP 7)

    mt_rand ( void ) : int

    mt_rand ( int $min , int $max ) : int

    参数

    min    可选的、返回的最小值(默认:0)

    max    可选的、返回的最大值(默认:mt_getrandmax())

    返回值   返回 min (或者 0) 到 max (或者是到 mt_getrandmax() ,包含这个值)之间的随机整数。

    很多老的 libc 的随机数发生器具有一些不确定和未知的特性而且很慢。PHP 的 rand() 函数默认使用 libc 随机数发生器。mt_rand() 函数是非正式用来替换它的。该函数用了 » Mersenne Twister 中已知的特性作为随机数发生器,它可以产生随机数值的平均速度比 libc 提供的 rand() 快四倍。

    如果没有提供可选参数 min 和 max,mt_rand() 返回 0 到 mt_getrandmax() 之间的伪随机数。例如想要 5 到 15(包括 5 和 15)之间的随机数,用mt_rand(5, 15)。

    总结

    min, max 参数皆为可选,规定随机数产生的范围。

    如果没有提供可选参数 min 和 max,则返回 0 到 RAND_MAX 之间的伪随机整数。

    例如,想要 1 到 100(包括 1 和 100)之间的随机数,用 rand(1, 100) 或 mt_rand(1,100)。

    mt_rand()是更好地随机数生成器(推荐使用),因为它跟rand()相比播下了一个更好地随机数种子;而且性能上比rand()快4倍,mt_getrandmax()所表示的数值范围也更大。

    注: 自 PHP 4.2.0 起,PHP产生随机数都不再需要用 srand() 或 mt_srand() 函数产生随机种子,已经会自动完成。

    PHP生成指定范围内的N个不重复的随机数

    有时候需要生成指定范围内一定数量的不重复随机数,例如生成100个20位随机数,具体怎么设计这个生产随机数的函数呢?

    方法1:可以将随机产生的数存入数组,并在存入的同时去除重复的值,即可生成一定数量的不重复随机数。

    方法2:可以把指定范围内的数值存进数组,再使用shuffle($array)打乱这个数组,然后再截取其中一定数量的值。

    说明:方法2的做法,在指定的随机数范围太大的时候会产生一个较大的数组。

    下面给出第一种做法的代码,第二种做法更简单,大家可以尝试下

    /**

    * 生成一定数量的不重复随机数,指定的范围内整数的数量必须比要生成的随机数数量大

    * https://mimvp.com in 2019.05.20

    *

    * @param string $min:指定随机数的最小值(包含)

    * @param string $max:指定随机数的最大值(包含)

    * @param string $num: 指定生成数量

    * @return array $result: 返回指定数量的随机数结果数组

    *

    * array_flip() 函数返回一个反转后的数组,如果同一值出现了多次,则最后一个键名将作为它的值,所有其他的键名都将丢失

    */

    function generate_unique_rand($min, $max, $num) {

    $count = 0;

    $result = array();

    while ($count < $num) {

    $result[] = mt_rand($min, $max);

    // $result = array_flip(array_flip($result));// 通过两次反转让随机数唯一, 使用 array_unique 替代

    $result = array_unique($result);// 返回唯一性元素的数组

    $count = count($result);

    }

    shuffle($result);// shuffle() 函数把数组中的元素按随机顺序重新排列, 打乱数组重新赋予数组新的下标

    return $result;

    }

    //生成10个1到100范围内的不重复随机数

    $unique_rand_array = generate_unique_rand(10, 99, 10);// 10, 90, 91(极限测试,死循环)

    sort($unique_rand_array);// 对返回的随机数排序, 方便查看

    print( sprintf("
    count: %d, unique_rand_array: %s", count($unique_rand_array), json_encode($unique_rand_array)) );

    shuffle($unique_rand_array);// 对返回的随机数排序, 随机顺序重新排列

    print( sprintf("
    count: %d, unique_rand_array: %s", count($unique_rand_array), json_encode($unique_rand_array)) );

    运行的结果:

    count: 10, unique_rand_array: [11,34,37,45,72,79,85,87,90,96]

    count: 10, unique_rand_array: [79,90,96,72,11,85,87,37,45,34]

    说明:

    1、生成随机数时我们用了 mt_rand() 函数。这个函数生成随机数的平均速度要比 rand() 快几倍。

    2、去除数组中的重复值时用了“翻转法”,就是用 array_flip() 把数组的 key 和 value 交换两次,这种做法在去除数组重复值的同时效率也比用 array_unique() 快得多。

    3、返回数组前,先使用 shuffle() 为数组赋予新的键名,保证键名是 0-n 连续的数字。如果不进行此步骤,可能在删除重复值时造成键名不连续,如果用for遍历的时候会有问题,但如果用foreach或不需要遍历的时候可以不需要shuffle。

    mt_rand() 和 rand() 速度测试

    测试代码

    /**

    * 功能: mt_rand() 和 rand() 速度测试

    * 版权: https://mimvp.com

    * 日期: 2019-05-20

    */

    function microtime_float() {

    list($usec, $sec) = explode(" ", microtime());

    return ((float)$usec + (float)$sec);

    }

    print("
    microtime_float(): " . microtime_float());

    function test_rand_mtrand($count=10000) {

    print("
    count: $count");

    // rand()

    $time_start = microtime_float();

    for($i=0; $i

    {

    rand();

    }

    $time_end = microtime_float();

    $time_cost = $time_end - $time_start;

    echo "
    rand() time_cost ---------- $time_cost seconds";

    // mt_rand()

    $time_start = microtime_float();

    for($i=0; $i

    {

    mt_rand();

    }

    $time_end = microtime_float();

    $time_cost = $time_end - $time_start;

    echo "
    mt_rand() time_cost ----- $time_cost seconds";

    }

    test_rand_mtrand(1000);// 1千次

    test_rand_mtrand(10000);// 1万次

    test_rand_mtrand(100000);// 10万次

    test_rand_mtrand(1000000);// 100万次

    test_rand_mtrand(10000000);// 1000万次(耗时较长)

    ?>

    运行结果:

    microtime_float(): 1559201781.7574

    count: 1000

    rand() time_cost ---------- 0.00091695785522461 seconds

    mt_rand() time_cost ----- 0.00093388557434082 seconds

    count: 10000

    rand() time_cost ---------- 0.008936882019043 seconds

    mt_rand() time_cost ----- 0.010462999343872 seconds

    count: 100000

    rand() time_cost ---------- 0.076805114746094 seconds

    mt_rand() time_cost ----- 0.074769020080566 seconds

    count: 1000000

    rand() time_cost ---------- 0.857342004776 seconds

    mt_rand() time_cost ----- 0.76551508903503 seconds

    count: 10000000

    rand() time_cost ---------- 7.561311006546 seconds

    mt_rand() time_cost ----- 7.7968890666962 seconds

    结论:两者的循环效率实际上差不多,没有传说中的相差4倍

    参考推荐:

    展开全文
  • 深度解密 Go math/rand

    2021-06-10 00:22:19
    Go 获取随机数是开发中经常会用到的功能, 不过这个里面还是有一些坑存在的, 本文将完全剖析 Go math/rand, 让你轻松使用 Go Rand.开篇一问: 你觉得 rand 会 p...

    Go 获取随机数是开发中经常会用到的功能, 不过这个里面还是有一些坑存在的, 本文将完全剖析 Go math/rand, 让你轻松使用 Go Rand.

    开篇一问: 你觉得 rand 会 panic 吗 ?

    rand panic

    源码剖析

    math/rand 源码其实很简单, 就两个比较重要的函数:

    func (rng *rngSource) Seed(seed int64) {
     rng.tap = 0
     rng.feed = rngLen - rngTap
    
     //...
     x := int32(seed)
     for i := -20; i < rngLen; i++ {
      x = seedrand(x)
      if i >= 0 {
       var u int64
       u = int64(x) << 40
       x = seedrand(x)
       u ^= int64(x) << 20
       x = seedrand(x)
       u ^= int64(x)
       u ^= rngCooked[i]
       rng.vec[i] = u
      }
     }
    }
    

    这个函数就是在设置 seed, 其实就是对 rng.vec 各个位置设置对应的值. rng.vec 的大小是 607.

    func (rng *rngSource) Uint64() uint64 {
     rng.tap--
     if rng.tap < 0 {
      rng.tap += rngLen
     }
    
     rng.feed--
     if rng.feed < 0 {
      rng.feed += rngLen
     }
    
     x := rng.vec[rng.feed] + rng.vec[rng.tap]
     rng.vec[rng.feed] = x
     return uint64(x)
    }
    

    我们在使用不管调用 Intn(), Int31n() 等其他函数, 最终调用到就是这个函数. 可以看到每次调用就是利用 rng.feed rng.tap 从 rng.vec 中取到两个值相加的结果返回了. 同时还是这个结果又重新放入 rng.vec.

    在这里需要注意使用 rng.go 的 rngSource 时, 由于 rng.vec 在获取随机数时会同时设置 rng.vec 的值, 当多 goroutine 同时调用时就会有数据竞争问题. math/rand 采用在调用 rngSource 时加锁  sync.Mutex 解决.

    func (r *lockedSource) Uint64() (n uint64) {
     r.lk.Lock()
     n = r.src.Uint64()
     r.lk.Unlock()
     return
    }
    

    另外我们能直接使用rand.Seed(),rand.Intn(100), 是因为 math/rand 初始化了一个全局的 globalRand 变量.

    var globalRand = New(&lockedSource{src: NewSource(1).(*rngSource)})
    
    func Seed(seed int64) { globalRand.Seed(seed) }
    
    func Uint32() uint32 { return globalRand.Uint32() }
    

    需要注意到由于调用 rngSource 加了锁, 所以直接使用rand.Int32()会导致全局的 goroutine 锁竞争, 所以在高并发场景时, 当你的程序的性能是卡在这里的话, 你需要考虑利用New(&lockedSource{src: NewSource(1).(*rngSource)})为不同的模块生成单独的 rand. 不过根据目前的实践来看, 使用全局的 globalRand 锁竞争并没有我们想象中那么激烈. 使用 New 生成新的 rand 里面是有坑的, 开篇的 panic 就是这么产生的, 后面具体再说.

    种子(seed)到底起什么作用 ?

    func main() {
     for i := 0; i < 10; i++ {
      fmt.Printf("current:%d\n", time.Now().Unix())
      rand.Seed(time.Now().Unix())
      fmt.Println(rand.Intn(100))
     }
    }
    

    结果:

    current:1613814632
    65
    current:1613814632
    65
    current:1613814632
    65
    ...
    

    这个例子能得出一个结论: 相同种子, 每次运行的结果都是一样的. 这是为什么呢?

    在使用 math/rand 的时候, 一定需要通过调用 rand.Seed 来设置种子, 其实就是给 rng.vec 的 607 个槽设置对应的值. 通过上面的源码那可以看出来, rand.Seed 会调用一个 seedrand 的函数, 来计算对应槽的值.

    func seedrand(x int32) int32 {
     const (
      A = 48271
      Q = 44488
      R = 3399
     )
    
     hi := x / Q
     lo := x % Q
     x = A*lo - R*hi
     if x < 0 {
      x += int32max
     }
     return x
    }
    

    这个函数的计算结果并不是随机的, 而是根据 seed 实际算出来的. 另外这个函数并不是随便写的, 是有相关的数学证明的.

    这也导致了相同的 seed, 最终设置到 rng.vec里面的值是相同的, 通过 Intn 取出的也是相同的值.

    我遇到的那些坑

    1. rand panic

    文章开头的截图就是项目开发中使用别人封装的底层库, 在某天出现的 panic. 大概实现的代码:

    // random.go
    
    var (
     rrRand = rand.New(rand.NewSource(time.Now().Unix()))
    )
    
    type Random struct{}
    
    func (r *Random) Balance(sf *service.Service) ([]string, error) {
     // .. 通过服务发现获取到一堆ip+port, 然后随机拿到其中的一些ip和port出来
     randIndexes := rrRand.Perm(randMax)
    
     // 返回这些ip 和port
    }
    
    

    这个 Random 会被并发调用, 由于 rrRand 不是并发安全的, 所以就导致了调用 rrRand.Perm 时偶尔会出现 panic 情况.

    在使用 math/rand 的时候, 有些人使用 math.Intn(), 看了下注释发现是全局共享了一个锁, 担心出现锁竞争, 所以用 rand.New 来初始化一个新的 rand, 但是要注意到 rand.New 初始化出来的 rand 并不是并发安全的.

    修复方案: 就是把 rrRand 换成了 globalRand, 在线上高并发场景下, 发现全局锁影响并不大.

    2. 获取的都是同一个机器

    流量不均匀

    同样也是底层封装的 rpc 库, 使用 random 的方式来流量分发, 在线上跑了一段时间后, 流量都路由到一台机器上了, 导致服务直接宕机. 大概实现代码:

    func Call(ctx *gin.Context, method string, service string, data map[string]interface{}) (buf []byte, err error) {
     ins, err := ral.GetInstance(ctx, ral.TYPE_HTTP, service)
     if err != nil {
      // 错误处理
     }
     defer ins.Release()
    
     if b, e := ins.Request(ctx, method, data, head); e == nil {
      // 错误处理
     }
     // 其他逻辑, 重试等等
    }
    
    func GetInstance(ctx *gin.Context, modType string, name string) (*Instance, error) {
     // 其他逻辑..
    
     switch res.Strategy {
     case WITH_RANDOM:
      if res.rand == nil {
       res.rand = rand.New(rand.NewSource(time.Now().Unix()))
      }
      which = res.rand.Intn(res.count)
     case 其他负载均衡查了
     }
    
     // 返回其中一个ip和port
    }
    

    引起问题的原因: 可以看出来每次请求到来都是利用 GetInstance 来获取一个 ip 和 port, 如果采用 Random 方式的流量负载均衡, 每次都是重新初始化一个 rand. 我们已经知道当设置相同的种子, 每次运行的结果都是一样的. 当瞬间流量过大时, 并发请求 GetInstance, 由于那一刻 time.Now().Unix() 的值是一样的, 这样就会导致获取到随机数都是一样的, 所以就导致最后获取到的 ip, port 都是一样的, 流量都分发到这台机器上了.

    修复方案: 修改成 globalRand 即可.

    rand 未来期望

    说到这里基本上可以看出来, 为了防止全局锁竞争问题, 在使用 math/rand 的时候, 首先都会想到自定义 rand, 但是就容易整出来莫名其妙的问题.

    为什么 math/rand 需要加锁呢?

    大家都知道 math/rand 是伪随机的, 但是在设置完 seed 后, rng.vec 数组的值基本上就确定下来了, 这明显就不是随机了, 为了增加随机性, 通过 Uint64() 获取到随机数后, 还会重新去设置 rng.vec. 由于存在并发获取随机数的需求, 也就有了并发设置 rng.vec 的值, 所以需要对 rng.vec 加锁保护.

    使用 rand.Intn() 确实会有全局锁竞争问题, 你觉得 math/rand 未来会优化吗? 以及如何优化? 欢迎留言讨论.

    展开全文
  • rand()和rand_r()的区别

    2021-12-16 12:54:48
    randrand_r

    背景

    最近在学《并行程序设计导论》这门课,在做使用Pthreads并行化蒙特卡洛法估计 π \pi π的实验时遇到了一个问题,使用多线程反而要比单线程要慢很多,输出如下所示
    请添加图片描述
    可以看到,使用一个线程时程序运行只需要2.89031秒,但是使用两个线程时运行时间竟然达到了9.14698秒。
    最终发现了问题所在:每个线程在执行下面的函数时,生成随机数使用了rand()函数,就是这个函数的使用才导致多线程运行时所需要的时间反而更长

    long long total_times_in_cycle;
    long long local_number_toss;
    pthread_mutex_t times_in_cycle_mutex = PTHREAD_MUTEX_INITIALIZER;
    void* do_Monte_Carlo_simulation(void* my_rank){
    	double offset = RAND_MAX / (double)2;
        long long times_in_cycle = 0;
        long long i;
        for(i = 0; i < local_number_toss; ++i){
            double x = rand() / offset - 1;
            double y = rand() / offset - 1;
            if(x*x + y*y < 1){
                times_in_cycle++;
            }
        }
        pthread_mutex_lock(&times_in_cycle_mutex);
        total_times_in_cycle += times_in_cycle;
        pthread_mutex_unlock(&times_in_cycle_mutex);
    }
    

    rand()和rand_r()的区别

    权威的解释请参考Linux的官方文档
    这里主要说说我个人的理解。

    rand()

    对于rand():

    1. srand()和rand()配套一起使用,可以认为是进程只生成了一个随机数生成器,所有的线程共用这个随机数生成器。每调用一次rand(),rand()都会去修改这个随机数生成器的一些参数,比如说当前种子的值。
    2. 对于单线程,这样是没有问题的,但是对于多线程而言,这显然会导致临界段问题,为了解决该问题,可能会使用互斥量等方法,下面假设多个线程同时使用rand()的时候使用互斥量来解决该临界段问题。
    3. 如果rand()调用的次数不多,多线程也问题不大,但是对于上述蒙特卡洛法估计 π \pi π的程序,需要调用很多次rand(),这可能会导致每个线程频繁地对临界段进行上锁和解锁,而临界段被上锁后,其他线程无法完成rand()的调用从而被阻塞,这样会导致效率十分低下,因此会出现使用多线程反而程序运行更慢的问题。

    srand()和rand()配套一起使用,可以认为是进程只生成了一个随机数生成器,所有的线程共用这个随机数生成器 这点可以用下面的程序进行验证,该程序从命令行获取要生成随机数的数量以及线程的数量,每个线程负责生成 随机数的数量/线程的数量 个随机数,随机数种子设为0.

    #include<stdio.h>
    #include<pthread.h>
    #include<stdlib.h>
    
    int generate_rand_count;
    int thread_count;
    
    // 被线程执行的函数
    void* thread_func(void* my_rank){
        int i;
        int local_rand_count = generate_rand_count / thread_count;
        for(i = 0; i < local_rand_count; ++i){
            printf("%d ", rand());
        }
    }
    
    int main(int argc, char* argv[]){
        pthread_t* all_threads_id;
    
        // 从命令行获取要生成的随机数的数量以及这些随机数由多少个线程来生成
        generate_rand_count = strtol(argv[1], NULL, 10);
        thread_count = strtol(argv[2], NULL, 10);
        all_threads_id = malloc(sizeof(pthread_t) * thread_count);
    
        // 设置随机数种子
        srand(0);
    
        // 创建线程
        int i;
        for(i = 0; i < thread_count; ++i){
            pthread_create(&all_threads_id[i], NULL, thread_func, (void*) i);
        }
    
        for(i = 0; i < thread_count; ++i){
            pthread_join(all_threads_id[i], NULL);
        }
        
        printf("\n");
        free(all_threads_id);
        return 0;
    }
    

    执行结果如下所示
    请添加图片描述
    可以看到,无论使用一个线程生成10个随机数,还是说使用两个线程来生成10个随机数,它们生成的这10个随机数是一样的,这也就验证了 所有的线程共用一个随机数生成器 的观点

    rand_r()

    rand_r()的声明如下所示

    int rand_r(unsigned int *seedp);
    

    每次使用rand_r()的时候需要传给该函数一个随机数种子的指针,为了解决蒙特卡洛方法估计 π \pi π中出现的问题,使用如下的代码:

    long long total_times_in_cycle;
    long long local_number_toss;
    pthread_mutex_t times_in_cycle_mutex = PTHREAD_MUTEX_INITIALIZER;
    void* do_Monte_Carlo_simulation(void* my_rank){
    	unsigned int local_seed = time(NULL);
    	double offset = RAND_MAX / (double)2;
        long long times_in_cycle = 0;
        long long i;
        for(i = 0; i < local_number_toss; ++i){
            double x = rand_r(&local_seed) / offset - 1;
            double y = rand_r(&local_seed) / offset - 1;
            if(x*x + y*y < 1){
                times_in_cycle++;
            }
        }
        pthread_mutex_lock(&times_in_cycle_mutex);
        total_times_in_cycle += times_in_cycle;
        pthread_mutex_unlock(&times_in_cycle_mutex);
    }
    

    每个线程执行函数do_Monte_Carlo_simulation()
    使用上面的代码后,相当于每个线程生成了它自己独有的随机数生成器,这样就不会有临界段问题,从而解决了多线程运行时所需要的时间反而更长这个问题,下面为更改后程序的输出:
    请添加图片描述

    展开全文
  • 本文实例对比分析了php中随机函数mt_rand()与rand()性能问题。分享给大家供大家参考。具体分析如下:在php中mt_rand()和rand()函数都是可以随机生成一个纯数字的,... mt_rand() 范例,代码如下:echo mt_rand() . "n";...
  • PHP函数rand和mt_randmt_rand() 比rand() 快四倍很多老的 libc 的随机数发生器具有一些不确定和未知的特性而且很慢。PHP 的 rand() 函数默认使用 libc 随机数发生器。mt_rand() 函数是非正式用来替换它的。该函数用...
  • 众所周知,在MySQL中,如果直接 ORDER BY RAND() 的话,效率非常差,因为会多次执行。事实上,如果等值查询也是用 RAND() 的话也如此,我们先来看看下面这几个SQL的不同执行计划和执行耗时。首先,看下建表DDL,这是...
  • mysql的rand函数

    2021-01-18 18:35:14
    之前看到的写法是这样ROUND(ROUND(RAND(),5)*100000)这样写不太准确,有几率出现4位的情况,Rand() 函数是取 0 ~ 1(无限接近) 的随机函数如果 某此随机数取出的 是 0.05321那么这样转化出来的就是 5321 ,只有4位。...
  • SQL RAND() 函数

    2021-04-25 14:24:01
    SQL RAND 函数SQL 有一个 RAND 函数,用于产生 0 至 1 之间的随机数:SQL> SELECT RAND( ), RAND( ), RAND( );+------------------+-----------------+------------------+| RAND( ) | RAND( ) | RAND( ) ...
  • mt_rand() 比rand() 快四倍,很多老的 libc 的随机数发生器具有一些不确定和未知的特性而且很慢。PHP 的 rand() 函数默认使用 libc 随机数发生器。mt_rand() 函数是非正式用来替换它的。PHP函数rand和mt_randmt_rand...
  • 1、rand5()得到rand3()或rand7()类型题 通过rand5实现rand3很好实现,rand5的取值为[1,2,3,4,5]的值,但是rand3的取值[1,2,3],由此可得,当rand5随机到4,5时可以重新随机,因为每次随机到的概率是相同的。所以...
  • MySQL Rand()函数

    2021-02-07 04:20:57
    MySQL Rand() 函数可以被调用,以产生一个在 0 和 1 之间的随机数:mysql> SELECT RAND( ), RAND( ), RAND( ); +------------------+-----------------+------------------+ | RAND( ) | RAND( ) | RAND( ) ...
  • C语言srand和rand函数

    2021-05-21 15:37:56
    满意答案n263egq33djg推荐于 2017.11.29标准库(被包含于中)提供两个帮助生成伪随机数的函数: 函数一:int rand(void);从srand (seed)中指定的seed开始,返回一个[seed, RAND_MAX(0x7fff))间的随机整数。 函数二:...
  • go math/rand包详解

    2021-07-10 06:58:22
    go math/rand package rand import "math/rand" rand包实现了伪随机数生成器。 math_rand go官方标准文档 随机数从资源生成。包水平的函数都使用的默认的公共资源。该资源会在程序每次运行时都产生确定的序列。如果...
  • rand函数的用法相关问题:匿名网友:rand(产生随机数)相关函数srand表头文件#include定义函数int rand(void)函数说明rand()会返回一随机数值,范围在0至RAND_MAX 间。在调用此函数产生随机数前,必须先利用srand()设...
  • 式子如下:rand = rand*const_1 + c_var;srand函数就是给它的第一个rand值。用"int x = rand() % 100;"来生成 0 到 100 之间的随机数这种方法是不或取的,比较好的做法是: j=(int)(n*rand()/(RAND_MAX+1.0)) 产生...
  • C / C++ function - rand

    2021-02-15 11:11:51
    C / C++ function - rand Defined in header <stdlib.h> int rand (void); 0. 产生一定范围内的随机数 产生 [a, b) 的随机整数,使用 (rand() % (b - a)) + a;。 [0, (b - a) - 1] + a = [a, (b - 1)] = [a, ...
  • 一:如果你只要产生随机数而不需要设定范围的话,你只要用rand()就可以了:rand()会返回一随机数值, 范围在0至RAND_MAX 间。RAND_MAX定义在stdlib.h, 其值为2147483647。#include #include int main(){int i;for(i =...
  • c语言rand()

    2021-05-21 02:32:58
    用c语言产生随机数rand()在C语言中,rand()函数可以用来产生随机数,但是这不是真真意义上的随机数,是一个伪随机数,是根据一个数,我们可以称它为种子,为基准以某个递推公式推算出来的一系数。C语言中rand()%m是啥...
  • 有1道面试题:给你一个能生成1到5随机数的函数,用它写一个函数生成1到7的随机数,即使用函数rand5()来实现函数rand7()。本文记录一下现在的我的解题过程。关键点直接用rand5()实现rand7()好像不好做,那么反过来了...
  • rand()%100就是rand()的反回值除100和余数,所以这个结果一定是在[0,99]区别内的整数。如果写成这样 :400+rand()%100; 那它的取值范围就是 400同样的,如果是400+rand()%200; 那它的取值范围就是 400随机数,顾名思义...
  • rand()

    2021-05-25 02:25:48
    概述rand()函数是产生随机数的一个随机函数。C语言里还有 srand()函数等。(1)使用该函数首先应在开头包含头文件stdlib.h#include(C++建议使用#include,下同)(2)在标准的C库中函数rand()可以生成0~RAND_MAX之间的一...
  • 已有方法rand7可生成 1 到 7 范围内的均匀随机整数,试写一个方法rand10生成 1 到 10 范围内的均匀随机整数。 不要使用系统的Math.random()方法。 示例 1: 输入: 1 输出: [7] 示例 2: 输入: 2 输出: [8,...
  • 本文以type rand struct 为切入点,看下 Go 伪随机数的实现原理。 // A Rand is a source of random numbers. type Rand struct { src Source s64 Source64 // non-nil if src is source64 // readVal .
  • 更新(PHP 7.1):07000 This means that the output for the following functions have changes: rand(), shuffle(), str_shuffle(), and array_rand().这意味着自7.1版以来,两者都没有实际的区别。之前PHP 7.1:在...
  • rand7实现rand10

    2021-08-13 10:38:01
    已有方法 rand7 可生成 1 到 7 范围内的均匀随机整数,试写一个方法 rand10 生成 1 到 10 范围内的均匀随机整数。 不要使用系统的 Math.random() 方法。 分析 得到1-40 41-49舍弃 对于大于40的数,(大于40的随机数...
  • c语言 rand 的用法

    2021-05-19 06:14:12
    下面,学习啦小编为大家整理了c语言 rand 的用法,希望对你有帮助哦!一、步骤:写入头文件#include #include #include 变量的定义void main( void ) { int i,k;srand( (unsigned)time( NULL ) ); /*选取种子文件*/...
  • 四,RAND()与RAND(N)区别 每个种子产生的随机数序列是不同的,如果传入N参数执行RAND(N),则每次查询到的随机数都是固定的,如果没有传入N参数,则每次都是随机的值。如下所示: 1.mysql> SELECT RAND(),RAND(5); 2...
  • MySQL RAND()函数调用可以在0和1之间产生一个随机数:mysql> SELECT RAND( ), RAND( ), RAND( );+------------------+-----------------+------------------+| RAND( ) | RAND( ) | RAND( ) |+------------------...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 391,193
精华内容 156,477
关键字:

RAND()