[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: random_r functies



On 11/23/2011 12:02 PM, Vincent Zweije wrote:
On Tue, Nov 22, 2011 at 10:47:33PM +0100, Eric Meijer wrote:

||  Ik heb een progammeer-probleem en ik weet niet of het een bug is
||  of ik iets over het over het hoofd zie.
||  Voor een multi-threaded programma (in C++) wil ik een random
||  number generator gebruiken.  Hiervoor zijn de re-entrant versies
||  van de random en initstate nodig.  Deze probeer ik nu uit met een
||  simpel C programmaatje:
||
||  ---- testrand.c ----
||  #include<stdio.h>
||  #include<stdlib.h>
||
||  int main(int argc, char* argv[])
||  {
||    struct random_data state1;
||    const size_t bufsz = 256;
||    char buf1[bufsz];
||    int32_t r1;
||
||    fprintf(stderr, "%d\n", initstate_r(1u, buf1, bufsz,&state1));
||    random_r(&state1,&r1);
||    fprintf(stderr, "%d\n", r1);
||
||    return 0;
||  }

Valgrind weet het volgende te melden:

     Conditional jump or move depends on uninitialised value(s)
        at 0x4E6487E: initstate_r (random_r.c:243)
        by 0x40065E: main (testrand.c:11)

Er moet dus ergens nog initialisatie plaats vinden voordat het gaat
werken.

srandom(3) weet:

     If no seed value is provided, the random() function is automatically
     seeded with a value of 1.

Automatic seeding kan natuurlijk niet als je zelf met een state komt
aanzetten, want de library heeft geen manier om te weten of de state al
is geïnitialiseerd. Je zult dus wel eerst nog een srandom_r(3) op je
state moet loslaten.

Ciao.                                                           Vincent.
Hoi Vincent,

Ik denk dat de initstate_r functie bedoeld is om de state te initialiseren,
wat zou die anders doen? Het eerste argument van die functie is ook een seed. De segmentation fault krijg je ook al als je het programma beperkt tot alleen een initstate_r call. Het verschil tussen initstate_r en srandom_r is dat je met initstate de grootte van de gebruikte state kan instellen. Als je srandom_r drie keer gebruikt
dan krijg je ook een seg fault:
---- testrand.c ----

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

int main(int argc, char* argv[])
{
  struct random_data state1, state2, state3;
  const size_t bufsz = 256;
  char buf1[bufsz];
  int32_t r1, r2, r3;

  srandom_r(1u, &state1);
  srandom_r(2u, &state2);
  srandom_r(3u, &state3);
  random_r(&state1, &r1);
  random_r(&state2, &r2);
  random_r(&state3, &r3);
  fprintf(stderr, "%d %d %d\n", r1, r2, r3);

  return 0;
}
----
Als je srandom_r één keer gebruikt dan crashed het niet, maar het idee is juist meerdere
random number generators te aan te maken voor verschillende threads.
Ik puzzel nog wat verder.

Eric


Reply to: