do
Skompiluj z flagą -pthread (lub cokolwiek, czego używa Twój kompilator).
#include <stdio.h>
#include <pthread.h>
#define m (unsigned long)2147483647
#define q (unsigned long)127773
#define a (unsigned int)16807
#define r (unsigned int)2836
static unsigned long seed;
pthread_t t[20];
int lo, hi, done;
void *pseudorandom(void *id)
{
while(done)
{
int test;
hi = seed/q;
lo = seed%q;
test = a * lo - r * hi;
if (test > 0) seed = test;
else seed = test + m;
}
}
main()
{
int i;
seed = 54321;
done = 1;
for(i = 0; i < 20; i++)
{
pthread_create(&(t[i]), NULL, &pseudorandom, NULL);
}
for (i = 0; i < 10; i++)
{
printf("%lu\n", seed);
}
done = 0;
}
Nie jestem pewien, czy to się kwalifikuje, czy też nie w oparciu o standard „czas nie jest dozwolony”, ponieważ w zasadzie używa on harmonogramu jako źródła entropii, celowo ignorując bezpieczeństwo wątków. Działa przy użyciu dość podstawowej funkcji losowo-losowej ( generator liczb losowych Lehmera ) z początkowo zakodowanym początkowo ziarnem. Następnie rozpoczyna 20 wątków, w których wszystkie uruchamiają obliczenia Lehmera ze wspólnym zestawem zmiennych.
Wygląda na to, że działa całkiem dobrze, oto kilka kolejnych przebiegów:
comintern ~ $ ./a.out
821551271
198866223
670412515
4292256
561301260
1256197345
959764614
874838892
1375885882
1788849800
comintern ~ $ ./a.out
2067099631
953349057
1736873858
267798474
941322622
564797842
157852857
1263164394
399068484
2077423336
EDYCJA:
Zastanów się trochę i zdaj sobie sprawę, że to wcale nie jest czas. Nawet przy całkowicie deterministycznym harmonogramie entropia nie pochodzi z przedziałów czasowych - pochodzi z ładowania wszystkich uruchomionych procesów w systemie.
EDYCJA 2
Po zainspirowaniu się @Quincunx po opublikowaniu krzywej dzwonowej, zrzuciłem 12 MB losowości do pliku i przesłałem ją do CAcert . Nie przeszedł wszystkich trudnych testów, ale osiągnął szacunek 7.999573 z 8 w teście ENT (tylko potencjalnie deterministyczny). Co ciekawe, podwojenie liczby wątków pogorszyło sytuację.