random_rは使ってはいけない

random_r 関数は glibc が提供しているリエントラントな擬似乱数生成APIです。
複数のスレッドで乱数を使いたい場合はこれを使うべきらしい。*1

複数のスレッドが random() を使うような状況では、この関数を使用すべきではない。 その場合には random_r(3) を使うこと。

http://linuxjm.sourceforge.jp/html/LDP_man-pages/man3/random.3.html

ただ少なくともこのマニュアルが不十分で、man を読んだだけだと正しく使うことは出来ません。


以下に私の手元で 動いたように見える コードを示します。

/*
 * $ gcc -o test test.c && ./test
 */
#include <stdio.h>
#include <stdlib.h>

int main (int argc, char * argv[]) {
  struct random_data buf;
  char rand_st[256];
  /**
   * この行が無いとsegmentation fault
   */
  buf.state = (int32_t*)rand_st; // (1)
  initstate_r(1, rand_st, sizeof(rand_st)/sizeof(rand_st[0]), &buf); // (2)
  srandom_r(1, &buf);

  int32_t r;
  random_r (&buf, &r);
  printf("(%d)\n", r);
  return EXIT_SUCCESS;
}

(1) の部分のように、random_data::state に状態へのポインタを設定をしないと (2) の箇所でセグフォして死にます。
ググってみると、10年前の時点で直ってるとか直ってないとかぐだぐだ言ってますがはっきりしません。
https://lists.debian.org/debian-glibc/2006/01/msg00037.html


どうやら正しい使い方はどこにも書いて無さそうなので、正しく使うことは書いた本人以外には不可能な気がします…。

結論として、

  • 仕様、使い方が判然としないし
  • マニュアルに従うと(あろうことか)セグフォする

ので使ってはダメです。
どうすればいいのかはよく分かりません_(:3」∠)_

動作確認環境

*1:単にrandom()へのアクセスをシリアライズするだけじゃダメなのか?