Примечание: из OTP 18 erlang:now/0
и random
устарели, а OTP 20 удалит модуль random
. См. Коррекция времени и времени в Эрланге для получения дополнительной информации.Кроме того, вам больше не нужно выполнять посев для каждого процесса, если вы используете rand:uniform/0
.Следующее оставлено для справки.
Проблема в том, что вы используете random
неправильно.random:seed/0
будет всегда заполнять генератор случайных чисел одним и тем же начальным числом.Это не хорошо для того, что вы хотите.Скорее, вы можете использовать random:seed(erlang:now())
, чтобы заполнить его другим номером, а именно текущим временем.
"Что произойдет, если два вызова будут очень близки?"Вы можете спросить.Ну, ребята из Erlang подумали об этом, поэтому now/0
гарантированно всегда будет возвращать растущие числа:
Возвращает кортеж {MegaSecs, Secs, MicroSecs}, который истек с 00:00 по Гринвичу1 января 1970 г. (ноль часов) в предположении, что базовая ОС это поддерживает.В противном случае выбирается какой-то другой момент времени. Также гарантируется, что последующие вызовы этого BIF возвращают непрерывно увеличивающиеся значения. Следовательно, возвращаемое значение now () может использоваться для генерации уникальных временных меток, и если оно вызывается в строгом режиме.В цикле на быстрой машине время узла может стать искаженным.
(выделено мое)
Также обратите внимание, что random
PRNG является для каждого процесса, поэтому вы должны всегданачните ваш процесс с вызова сеялки:
init([..]) ->
random:seed(erlang:now()),
[..]
{ok, #state { [..] }}.
Использование ссылок для этого возможно возможно, но я не думаю, что это жизнеспособно.Решение выходит за рамки erlang:ref_to_list/1
, и это не красиво.