目录
一、获取随机数的函数
#include <cstdlib>
void srand(unsigned int seed);
int rand(void);
二、线程安全的初始化随机数种子
在调用 rand() 之前,需要先调用 srand() 来初始化随机数队列,但是全局只需要调用一次 srand() 就够了,所以对 srand() 的调用,可以是在 main 函数开始的时候只调用一次 srand(),然后其它地方都不再调用 了。也可以增加一种机制,让 srand() 在全局只被调用一次,例如下面的代码,保证了使用 RUN_ONCE 宏的地方在全局只被执行一次,即使是多线程情况下。
#define ONCE_RUN(code) { \
static int _done; \
if (!_done) { \
if (__sync_bool_compare_and_swap(&_done, 0, 1)) { \
code \
} \
} \
}
三、完整测试代码
下面是完整的生成随机数的代码,不需要再手动调用 srand() 函数,只需要调用 get_rand() 函数就可以了。 get_rand() 函数会自动调用srand() 设置随机数种子,并使用当前的微秒时间戳作为随机数种子。
#include <string>
#include <iostream>
#include <sys/time.h>
// for multthreads
#define ONCE_RUN(code) { \
static int _done; \
if (!_done) { \
if (__sync_bool_compare_and_swap(&_done, 0, 1)) { \
code \
} \
} \
}
void set_srand()
{
//使用微秒级的时间作为随机数的种子
struct timeval tv;
gettimeofday(&tv, nullptr);
unsigned long long usec = tv.tv_sec * 1e6 + tv.tv_usec;
srand(usec); // 设置随机数的种子
}
unsigned int get_rand(unsigned int min=0x0, unsigned int max=0xffffffff)
{
ONCE_RUN(set_srand(););
return rand() % (max - min) + min;
}
int main(int argc, char*argv[])
{
for(int i = 0; i < 10 ; i++)
{
std::cout << get_rand() % 10 << " "; // 产生随机数
}
std::cout << std::endl;
return 0;
}
四、编译及运行
$ g++ -g -Wall -I. --std=c++11 rand-number.cpp -o rand-number
$ ./rand-number
6 7 6 7 0 7 4 8 1 3
五、参考
https://blog.csdn.net/junh_tml/article/details/114675327
http://c.biancheng.net/view/1352.html