【问题标题】:Creating random numbers in a multithreaded program in C在 C 中的多线程程序中创建随机数
【发布时间】:2012-02-04 21:38:25
【问题描述】:

我正在编写一个程序,其中有创建随机数的工作线程 从 0 到 3 从0到x-1(一个变量)

我需要学习的是如何在 C 中生成这些随机数。

我正在使用 gcc 编译器并在 Ubuntu 11.10 上工作

【问题讨论】:

  • “从0到3从0到x-1”是什么意思?你的意思是你需要 x 个介于 0 到 3 之间的随机值
  • 您是想了解有关随机部分或多线程部分或两者的知识吗?
  • x 是一个 int 变量的名称。
  • 如果您使用的是 POSIX 系统,请尝试 drand48 functions 之一(可能是 nrand48())。
  • @littlestewie:请提供您的环境(平台、编译器)的详细信息,因为答案取决于此。

标签: c multithreading random


【解决方案1】:

使用rand_r()(参见rand(3))

函数 rand_r() 提供了一个指向 unsigned int 的指针, 用作状态。

它是可重入的,并将种子作为输入,因此线程可以单独管理它们的种子。

【讨论】:

    【解决方案2】:

    如果你只是想要一些随机数,而不关心随机数序列是否独立生成,你仍然可以使用rand()srand()

        #include <stdlib.h>                       
        #include <stdio.h>                        
        #include <pthread.h>                      
        #include <unistd.h>                       
    
        void* cb1(void*) {                        
            while(1) {                            
                printf("cb1, rand:%d\n",rand());  
                sleep(1);                         
            }                                     
        }                                         
    
        void* cb2(void*) {                        
            while(1) {                            
                printf("cb2, rand:%d\n",rand());  
                sleep(1);                         
            }                                     
        }                                         
    
    
        int main() {                              
            pthread_t  th1, th2;                  
            srand(1);                             
            pthread_create(&th1, NULL, cb1, NULL);
            pthread_create(&th2, NULL, cb2, NULL);
    
            pthread_join(th1, NULL);              
            pthread_join(th2, NULL);              
    
            return 0;                             
        }                                         
    

    【讨论】:

      【解决方案3】:

      使用 C11 的 threads.h 的简单版本,缺少错误检查,如下所示:

      mtx_t rand_mtx;
      
      //run only once.
      int rand_init(int seed)
      {
           srand(seed);
           mtx_init(&rand_mtx, mtx_plain);
      } 
      
      int synced_rand()
      {
          mtx_lock(&rand_mtx);
          int r = rand();
          mtx_unlock(&rand_mtx);
          return r;
      }
      

      【讨论】:

        【解决方案4】:

        真与美;

        http://en.wikipedia.org/wiki/Mersenne_twister

        编写你自己的 RNG。

        (抱歉。我刚刚查看了那个 wiki 页面。上次我看了一下,不久前,它很好;你可以阅读它并实现捻线器。现在它是一堆学位级别的数学,完全没有解释任何人,除了那些在大学学习了四年数学的人。我在 wiki 上经常看到这种情况 :-(

        【讨论】:

        • 也许不会太久 - 我的印象是,在讨论伪代码如何不是伪代码时发生了争执。预计该页面在不久的将来将完全无用:-/
        • 不要为生产使用自己编写。只是不要。存在调试良好的实现。
        【解决方案5】:

        rand() & srand() 在这种情况下不是可以安全使用的。

        它们都既不是可重入的也不是线程安全的。一般来说,C 或 C++ 标准都没有对任何标准库函数的线程安全提出任何要求。
        某些实现可能确实提供线程安全版本,但标准并未强制要求。

        为了能够在多线程环境中使用随机数生成器,您需要一个允许传入状态的实现。这样,您可以为每个线程保留一个状态值,并在不需要同步的情况下生成高质量的随机数。

        C 标准库不提供任何选择。这使得 100% 的可移植性几乎不可能。然后,使用的选择将取决于您的环境,您应该将其作为问题的一部分提及以获得准确的答案。

        看看声称提供MultiThreaded Random Number generatorGNU Scientific Library

        【讨论】:

        • 我之前在 Linux 和 Windows 上使用过 GSL,但没有出现问题 - 请注意,每个线程都需要自己的随机数生成器(使用 gsl_rng_alloc 创建)。也就是说,线程安全是通过拥有多个随机数生成器来实现的,每个生成器都有自己的状态,而不是每次使用生成器时都锁定状态。
        • 通常,当一个函数不是线程安全的时,你会得到意想不到的结果。但是如果rand返回了意想不到的结果,那有什么问题呢?
        • @ugoren:你最终可能会从一个应该给你随机值的函数中得到完全相同的值,这不是问题吗?
        • @Als,一个正确的rand() 实现也会以一定的概率给出两次完全相同的随机值。但原则上你是对的,因为正确的rand() 是一个已知的概率,而这里不是。如果它用于密码学,它实际上很重要。
        • 在模拟研究中,您经常希望能够复制“随机”模拟数据的结果。这就是为什么随机数生成器通常允许您亲自设置种子。所以这很重要。
        猜你喜欢
        • 2016-05-15
        • 2023-03-17
        • 1970-01-01
        • 1970-01-01
        • 2016-05-13
        • 2014-07-25
        • 2013-03-15
        • 2013-02-02
        • 1970-01-01
        相关资源
        最近更新 更多