Я разрабатываю несколько процессов, и мне нужно, чтобы каждый процесс выполнял задачу со случайно выбранными элементами.Я обнаружил, что разветвленные процессы выбирают одинаковые случайные числа.Я попытался создать семена и вызвать srand (), но это не сильно помогло.На самом деле, большая часть документации, которую я прочитал, предлагает избегать srand (), «если вы точно не знаете, что делаете».
Вот мой код:
#!/usr/bin/perl
use strict;
use warnings;
use Getopt::Long qw(GetOptions);
use Time::HiRes qw(time);
use MongoDB;
#use Math::Random::Secure qw(rand);
my $num_clients = shift;
my $num_loops = 50_000_000;
sub test_forked_sub {
my $sum=0;
my $random_offset = rand(120);
printf "time: %10.4f - Random offset: %6.2f at pid: %s \n", time(), $random_offset, $$;
for (my $i=0; $i < $num_loops ; $i++) {
$sum += rand(120);
}
}
my $nub_processes = 0;
for (my $client_id =0; $client_id < $num_clients; $client_id++ ) {
if (my $pid = fork) { #Parent
$nub_processes++;
}
else { # child
die "cannot fork: $!" unless defined $pid;
test_forked_sub();
exit(0);
}
}
while ($nub_processes){
wait;
$nub_processes--;
}
Когда я запускаю его, я получаю одинаковое «случайное» число в каждом из процессов:
$ time ./test_rand_fork.pl 10
time: 1569510011.6891 - Random offset: 46.64 at pid: 2091
time: 1569510011.6937 - Random offset: 46.64 at pid: 2092
time: 1569510011.6987 - Random offset: 46.64 at pid: 2093
time: 1569510011.7028 - Random offset: 46.64 at pid: 2094
time: 1569510011.7070 - Random offset: 46.64 at pid: 2095
time: 1569510011.7097 - Random offset: 46.64 at pid: 2096
time: 1569510011.7144 - Random offset: 46.64 at pid: 2097
time: 1569510011.7203 - Random offset: 46.64 at pid: 2098
time: 1569510011.7230 - Random offset: 46.64 at pid: 2099
time: 1569510011.7249 - Random offset: 46.64 at pid: 2100
real 0m3.974s
user 0m32.955s
sys 0m1.444s
Возможенно некрасивое решение, это не раскошелиться.Вместо этого, чтобы запустить несколько экземпляров из моей оболочки следующим образом:
# shell processes
$ for i in `seq 1 10`; do ./test_rand_fork.pl 1 & done
time: 1569511908.7708 - Random offset: 7.44 at pid: 4129
time: 1569511908.8070 - Random offset: 19.50 at pid: 4131
time: 1569511908.8068 - Random offset: 97.59 at pid: 4132
time: 1569511908.8073 - Random offset: 14.51 at pid: 4133
time: 1569511908.8077 - Random offset: 16.70 at pid: 4134
time: 1569511908.8080 - Random offset: 108.63 at pid: 4138
time: 1569511908.8079 - Random offset: 69.44 at pid: 4137
time: 1569511908.8080 - Random offset: 83.25 at pid: 4136
time: 1569511908.8080 - Random offset: 43.33 at pid: 4135
time: 1569511908.8203 - Random offset: 33.82 at pid: 4139
Поскольку «процессы оболочки» - ужасное решение, я попытался использовать Math :: Random :: Secure.Вот результаты, которые я получаю случайным образом по мере необходимости, но он в 50 раз медленнее, чем подход «процессов оболочки»:
# using: Math::Random::Secure qw(rand);
$ time ./test_rand_fork.pl 10
time: 1569510036.9331 - Random offset: 112.48 at pid: 2128
time: 1569510036.9470 - Random offset: 47.15 at pid: 2129
time: 1569510036.9501 - Random offset: 20.77 at pid: 2130
time: 1569510036.9517 - Random offset: 40.98 at pid: 2131
time: 1569510036.9521 - Random offset: 13.84 at pid: 2132
time: 1569510036.9538 - Random offset: 20.43 at pid: 2133
time: 1569510036.9543 - Random offset: 48.48 at pid: 2134
time: 1569510036.9563 - Random offset: 109.29 at pid: 2135
time: 1569510036.9579 - Random offset: 70.30 at pid: 2136
time: 1569510036.9601 - Random offset: 24.31 at pid: 2137
real 3m17.251s
user 32m31.129s
sys 0m1.054s
Случайность, которая мне нужна, не для целей безопасности, мне просто нужен хороший спред.Есть ли способ создать достаточно хорошее начальное число для разветвленных процессов и при этом использовать стандартный rand () или альтернативный более быстрый способ?или хотя бы то, что не требует установки дополнительной библиотеки?