【问题标题】:Generate uniformly distributed random number in Nginx?在 Nginx 中生成均匀分布的随机数?
【发布时间】:2017-09-01 23:23:26
【问题描述】:

Nginx 似乎有一个名为ngx_random 的内置函数,它在源代码的various places 中使用。但似乎只是定义为:#define ngx_random random

如果我理解正确,这意味着 Nginx 调用 ngx_random() 的所有地方都只是调用(在 Linux 平台上)random()。从doc 来看,我不清楚它是否保证以任何方式在给定范围内均匀分布,我怀疑它类似于 rand(),它是not uniform at all,并且只有在范围内才会是均匀的n 可以被 RAND_MAX 整除。

但是使用ngx_random 的好处是我相信系统会在启动期间自动处理播种。而如果我想在我的范围内使用真正统一的东西,比如drand48,我相信必须在ngx_posix_init.c 中的以下内容之后添加一个新行?

srandom(((unsigned) ngx_pid << 16) ^ tp->sec ^ tp->msec);
srand48(((unsigned) ngx_pid << 16) ^ tp->sec ^ tp->msec); //Added so that I can use drand48

那么我对ngx_random 的假设是否正确?如果我想在各个模块的任何地方使用drand48,以上是唯一的方法吗?

【问题讨论】:

    标签: c nginx random


    【解决方案1】:

    我自己从未尝试过使用 nginx,所以认为这只是一个想法。在 Linux(或类似的基于 ELF 的系统,例如 Solaris)上,您可以使用 LD_LIBRARY_PRELOAD 技巧来替换和/或截取标准 C 库中的弱符号。它通常用于拦截和/或替换 malloc,但也可能对您有用

    代码示例(未经测试,未编译,只是为了展示一个想法)

    #define _GNU_SOURCE
    
    #include <stdlib.h>
    #include <dlfcn.h>
    
    static void (*real_srandom)(uint32_t) = NULL;
    
    static void srandom_init(void) {
        real_srandom = dlsym(RTLD_NEXT, "srandom");
        if (NULL == real_srandom) {
            fprintf(stderr, "Error in `dlsym`: %s\n", dlerror());
        }
    }
    
    void srandom(uint32_t seed) {
        if(real_srandom == NULL) {
            srandom_init();
        }
    
        real_srandom(seed);
        srand48(seed);
    }
    

    您也可以编写 SO 来替换对 random(3) 的调用,将其替换为您自己的实现。唯一不能替换的是 RAND_MAX,因为它是常量编译的。

    我很高兴知道这个技巧是否适合你

    【讨论】:

    • 谢谢!这是一个有趣的想法。不幸的是,我无法在整个 nginx 映像中替换所有 random() 或 srandom() 函数 --- 源代码中的大多数地方都使用 random() 是有道理的,只是当我只想要均匀分布时,这不适合我的用例一个指定的范围。除了我将在 ngx_posix_init.c 中显式植入 srand48,然后在需要时使用 drand48() 之外,它看起来并没有太多可用的解决方法...
    • @Superziyi 好吧,你可以像我展示的那样将它们链接起来。链接可能是最安全的选择,因为它保证您不会错过任何 srandom() 调用。不管怎样,祝你好运
    • 啊我明白你的意思了...非常感谢,会试试看!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-12-09
    • 2013-05-10
    • 2013-07-22
    • 2012-09-18
    • 1970-01-01
    • 2018-10-04
    • 1970-01-01
    相关资源
    最近更新 更多