2

所以我一直在用 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 上生成随机数时,我有哪些替代方案,它也是线程安全的?

嗯,就是这样。

该示例使用 gcc 编译为,

gcc simple.c -o 简单

4

2 回答 2

5

我真的没有看到使用drand48_rover的好处erand48erand48具有相同类型的随机生成器,drand48但与之相比,它接收随机生成器的状态作为函数参数,因此它完美地完成了这项工作。

扩展将_r结果存储在适当的位置(第二个参数)并返回一个始终保证为0. 我认为所有这些都没有多大用处。我会坚持使用 POSIX 接口(尤其是erand48)。

于 2012-04-04T16:14:16.403 回答
4

使用 中的标准可重入函数<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()call来实现 Mac OS X erand48(),或者您可以移植并使用erand48()POSIX 定义的并且自 1980 年代以来在大多数 Unix 系统上都可用。就个人而言,我会追求可移植性,但编写一个简单drand48_r()的代码也很简单,只是要找出声明它的标头。

于 2012-04-04T16:15:37.287 回答