php - 随机数生成器是原子的吗
问题描述
rand() 函数什么时候改变它的种子值?
调用函数的第二个 php 实例是否有可能在函数的第一个实例更改种子值之前中断并启动 rand() 函数,从而将相同的结果返回给两个单独的 php 脚本实例?
解决方案
每个 PHP 实例都有自己的种子值。您可以随时通过调用更改种子值srand()
。
特定种子的随机序列可能会从 PHP 的一个版本更改为下一个版本(特别是在版本 4.2.0rand()
中引入了自动播种时,以及在版本 7.1.0中将 设为rand()
别名时mt_rand()
)。
但是,只要您使用的是相同版本的 PHP,连续调用rand()
aftersrand()
使用特定值返回的数字序列将始终完全相同。
更新,根据您的评论
但是,当您异步上传 20 个图像文件时,它们都运行相同的 php 脚本,并且在该脚本中是 rand() 函数,该函数用于返回随机数,该随机数用于从 16000 个可能的名称和 50 个范围内选择一个文件名用户 8 或 10 产生相同的文件名 我倾向于得出结论 rand() 不仅不是原子的,而且不同的 PHP 实例可能让 rand() 返回相同的结果。
您的问题没有提到您的重复文件名问题,这不太可能与
rand()
. 我建议您阅读生日悖论,这解释了为什么当n接近 400 时,从一组 16000 个项目中随机选择n个会产生几乎 100% 确定性的重复选择。从事物的声音来看,您有 50 个用户每个上传 20 个文件,因此多个上传文件被分配给同一个文件名的概率非常接近 1。或者换句话说,没有上传文件分配给同一个文件名的概率小于万亿分之一。你可以自己测试一下的原子性
rand()
。将以下内容复制到您的命令行:for n in $(seq 1 20) do sleep 0.05 php -r "srand(0); for (\$i=0; \$i<20000000; \$i++) rand(); echo '$n: ' . rand() . chr(10);" & done
这将创建 20 个同步进程,每个进程从同一个种子生成 2000 万个数字,然后输出序列中的最后一个数字。如果这些过程以任何方式相互干扰,那么您会认为输出是不稳定的。但他们不是。
这个问题的答案解释了如何为上传的文件生成唯一的文件名。
推荐阅读
- paypal - 处理中间人交易
- python - Reading parquet partitioned table from S3 using pyspark is dropping leading zeros from partition column
- html - 如何在 css 中调整锚点图像的大小?
- java - 打印方法对于 Java LinkedQueue 没有得到前面的值
- javascript - 有没有办法只使用 ajax 用新内容更新 div
- api - 如何防止 https 站点的 SSL 代理?
- python - 在 MySQL 中通过循环将 1NF 数据插入表中
- r - 来自月度数据的时间序列的日平均值 R monthdays()
- python - 使用逗号分隔的连接字符串写入文本文件的文本文件列表
- r - 从箱线图中提取平均值并执行 t.test