使用drand48_r作为C中的随机数生成器

时间:2012-04-04 16:03:51

标签: c macos random openmp gnu

所以我一直在用C编写一些应用程序并使用OpenMP进行并行化。我实现了一个Monte-Carlo Pi估计,发现正常的rand()函数不是重入和线程安全的。建议使用drand48_r选项。

现在问题是,我的应用程序在Linux上编译得很好,例如。 Ubuntu,Fedora和CentOS但不能在Mac OS X上编译.OS X上的编译错误是。

  

simple.c:7:错误:'randBuffer'的存储大小未知

用作简单示例的代码是:

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char* argv[]) {

  double x;
  struct drand48_data randBuffer;

  srand48_r(time(NULL), &randBuffer);

  drand48_r(&randBuffer, &x);

  printf("Random number: %f\n", x);

  return EXIT_SUCCESS;
}

我读到了它并在手册页中找到了一条注释,

  

这些功能是GNU扩展,不可移植。

以下是指向它的链接:http://www.kernel.org/doc/man-pages/online/pages/man3/drand48_r.3.html

所以我有很多问题;

  1. 什么是GNU扩展以及什么使它不可移植?
  2. 我还有哪些替代方法可以在OS X上生成随机数,这也是线程安全的?
  3. 那就是它。

    该示例使用gcc编译,

      

    gcc simple.c -o simple

2 个答案:

答案 0 :(得分:4)

我真的没有看到使用drand48_r超过erand48的好处。 erand48具有与drand48相同类型的随机生成器,但与将其作为函数参数接收随机生成器的状态进行比较,因此它完美地完成了工作。

_r扩展名将结果存储到位(第二个参数),并返回始终保证为0的错误代码。我并没有在这一切中看到太多用处。我坚持使用POSIX接口(特别是erand48)。

答案 1 :(得分:3)

使用<stdlib.h>中的标准可重入函数。他们只是简单地预先列出了无处不在的_r后缀,因此他们的名字是:

 #include <stdlib.h>

 double drand48(void);

 double erand48(unsigned short xsubi[3]);

 long jrand48(unsigned short xsubi[3]);

 void lcong48(unsigned short param[7]);

 long lrand48(void);

 long mrand48(void);

 long nrand48(unsigned short xsubi[3]);

 unsigned short *seed48(unsigned short seed16v[3]);

 void srand48(long seedval);

erand48()函数采用数据结构(实际上是3个无符号短路的数组)作为其状态。因此,您可以通过将其绑定到本地定义的drand48_r()结构并进行drand48_data调用drand48_r()来为Mac OS X实施erand48(),或者您可以移植并使用{{由POSIX定义并且自20世纪80年代以来在大多数Unix系统上可用。就个人而言,我会考虑可移植性,但写一个简单的drand48_r()也是直截了当的,除了整理出哪个标题声明它。