金庆的专栏

  C++博客 :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理 ::
  423 随笔 :: 0 文章 :: 454 评论 :: 0 Trackbacks
线程安全的随机数生成

(金庆的专栏)

* rand()不可重入
* 用线程专用存储保存随机数生成器
* 自动设置随机种子为设备随机数
* 线程退出时,自动析构生成器

typedef boost::random::mt19937 Generator;

static Generator & GetGen()
{
    static boost::thread_specific_ptr<Generator> s_pRng;
    Generator * pRng = s_pRng.get();
    if (pRng) return *pRng;

    s_pRng.reset(new Generator);
    s_pRng->seed(boost::random_device()());
    return *s_pRng.get();    
}

Uint32 Rand32()
{
    return GetGen()();
}

// Random in [nFrom, nTo].
int Rand(int nFrom, int nTo)
{
    if (nFrom > nTo)
        boost::swap(nFrom, nTo);
    BOOST_ASSERT(nFrom <= nTo);
    boost::random::uniform_int_distribution<int> dist(nFrom, nTo);
    return dist(GetGen());
}
posted on 2013-01-23 18:30 金庆 阅读(3147) 评论(5)  编辑 收藏 引用 所属分类: 1. C/C++

评论

# re: 线程安全的随机数生成[未登录] 2013-03-18 14:48 春秋十二月
有问题吧,static变量s_pRng是线程安全的吗?  回复  更多评论
  

# re: 线程安全的随机数生成 2013-03-18 19:01 金庆
@春秋十二月
当然是线程安全的。  回复  更多评论
  

# re: 线程安全的随机数生成[未登录] 2013-03-19 14:31 春秋十二月
当多个线程进入GetGen函数时,s_pRng的初始化能保证是安全的吗?shared_ptr只保证其引用计数的维护是线程安全的,但变量本身的初始化,拷贝、赋值等,则不是。  回复  更多评论
  

# re: 线程安全的随机数生成 2013-03-19 16:00 金庆
@春秋十二月
多线程调用时,局部静态变量s_pRng可能并发多次初始化。多谢指出。thread_specific_ptr的示例代码中用的是全局变量,只有一次初始化。
还是改成全局静态变量好了。

typedef boost::random::mt19937 Generator;
static boost::thread_specific_ptr<Generator> s_pRng;

static Generator & GetGen()
{
Generator * pRng = s_pRng.get();
...
}  回复  更多评论
  

# re: 线程安全的随机数生成 2013-03-20 23:06 春秋十二月
嗯,我一般不轻易在函数内使用static变量,要么全局,要么使用线程安全的单件  回复  更多评论
  


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理