initstate vs initstate_r:令人困惑的参数

时间:2014-08-07 14:11:31

标签: c random

我试图了解initstateinitstate_r的联合帮助页。这两个函数都在初始化随机生成器。如果您有多个线程,则不应使用initstate但是对于该场景,您应该使用initstate_r

这些功能的签名是

char *initstate(unsigned int seed, char *state, size_t n);
int initstate_r(unsigned int seed, char *statebuf,
                size_t statelen, struct random_data *buf);

和联机帮助页的说明

   The initstate() function allows a state array state to be initialized  for  use  by  random().
   The size of the state array n is used by initstate() to decide how sophisticated a random num‐
   ber generator it should use—the larger the state array, the better the random numbers will be.
   seed  is the seed for the initialization, which specifies a starting point for the random num‐
   ber sequence, and provides for restarting at the same point.

   The  initstate_r()  function  is like initstate(3) except that it initializes the state in the
   object pointed to by buf, rather than initializing the global state variable.

我不明白为什么有两个参数在initstate_rstatebufbuf的情况下保持随机生成器的状态。如果偶数initstate具有保持随机数生成器状态的参数state,为什么还需要initrand_r的附加参数?他们不应该持有相同的信息吗?

并且statebufbuf都必须是线程本地的吗?

1 个答案:

答案 0 :(得分:0)

两者都必须是本地线程。

至于为什么你需要两者,嗯,这是一个(imho认为不好)的设计选择。 他们可能(应该?)将状态隐藏在random_data中,特别是因为random_data必须足够大才能保存srandom_r的状态(即大小为128的缓冲区)。

#include <stdlib.h>
#include <stdio.h>
int main()
{
        int32_t i32;
        struct random_data r;
        srandom_r(1, &r);
        random_r(&r, &i32);
        return i32;
}

除了上面的段错误(即使你先将r vaiable归零):通过阅读https://sourceware.org/git/?p=glibc.git;a=blob_plain;f=stdlib/random_r.c;hb=656b84c2ef525e3b69802c9057c5897e327b0332,看起来他们希望你为随机数组提供存储,即srandom()选择一个默认大小为128,srandom_r希望您为状态数组提供空间。

我想,基本原理是状态数组可能是“大”(最多256个字节),因此它们不会分配可能浪费的空间(有些人会为它们的线程保留一个小的堆栈大小)。 / p>

关于statebufbuf之间的区别:statebuf包含random_r所需的信息,即状态数组及其元数据(大小等)以压缩格式显示(不透明)传统上被压缩statebuf[0] - 例如:第1个字节=大小,第2个字节= ...),而bufstatebuf的“解包”版本,因此实施起来更方便random_r。

我认为这更像是一种咆哮而不是一种答案 - 让我知道是否有任何特别难以理解的事情:)