在多个线程上使用random()函数

时间:2013-06-28 03:28:54

标签: ios multithreading random thread-safety

我正在开发一款需要可重复随机数的应用。我使用srandom()和种子来初始化随机数序​​列。然后我使用random()从这个种子生成随机数。如果这是唯一生成随机数的线程,一切正常。但是,如果有多个线程生成随机数,它们会相互干扰。

显然,随机数序列不是线程安全的。必须有一个由所有线程调用的中央随机数生成器。

我的应用程序生成数百个对象,每个对象都有四个由14个随机数组成的序列。这4个序列中的每一个都有自己的非随机种子。这样,随机数应该是可重现的。问题是,由于我刚刚描述的线程干扰,有时生成的14个数字的序列将被另一个线程的随机数请求中断。

在考虑了一段时间之后,我决定打电话给

dispatch_sync(dispatch_get_main_queue(), ^{//generate the 14 numbers}); 

获取每个序列。这应该强制它们以正确的顺序生成。在阅读文档时,它表示如果在运行的队列中调用dispatch_sync,可能会出现死锁。如何判断我是否已经在主队列中?如果我,我不需要发送任何东西,对吗?

有更好的方法吗?

我怀疑另一种方法与此类似,但使用专用队列而不是主队列。我以前从未尝试过自己的队列。此外,需要调用队列的方法是一个短暂的方法,所以如果我要去那条路线,我需要以某种方式传递自定义队列。如何将队列作为参数传递?

现在,我正在运行我的想法,上面,同步调度到主队列,应用程序似乎工作正常。在最糟糕的情况下,这段代码将运行大约4800次(1200个对象中的每个对象4个,目前是最大值)。

2 个答案:

答案 0 :(得分:0)

我假设你想要计算随机数,而不是加密随机数。

我的建议是为每个线程分别设置RNG,每个线程RNG从主RNG集中播种。由于系统RNG不是线程安全的,因此创建自己的小型RNG方法 - 一个好的LCG应该可以工作 - 只能在一个线程中使用。

使用内置random()仅为每个子线程生成初始种子。使用srandom()设置整体初始种子将确保线程本地my_random()方法将获得一致的初始重新设置,只要每次以相同的顺序启动线程。

实际上,您正在构建RNG的层次结构以匹配您的线程层次结构。

答案 1 :(得分:0)

另一个选择是让单身人员进行计算。需要这组随机数的对象会批量询问单例。