对分叉的孩子调用rand/mt_rand会产生相同的结果 [英] Calling rand/mt_rand on forked children yields identical results
问题描述
我正在编写一个脚本,该脚本需要在PHP中执行并发任务.
I'm writing a script that needs to execute concurrent tasks in PHP.
我进行了一些测试,并遇到了奇怪的结果.我正在使用pcntl_fork生成一个孩子.父进程什么也没做,只是等待子进程完成.
I ran a little test and ran into strange result. I'm using pcntl_fork to generate a child. The parent process does nothing but wait for the child to complete.
我要生5个孩子,每个孩子都运行一个函数,该函数生成一个随机数(秒),并睡眠那么长时间.由于某些原因-所有孩子都会产生相同的数字.
I'm generating 5 children, each child runs a function that generates a random number (of seconds) and sleeps for that long. For some reason - all children generate the same number.
这是一个代码示例:
private $_child_count = 0;
private function _fork_and_exec($func)
{
$cid = ++$this->_child_count;
$pid = pcntl_fork();
if ($pid){ // parent
return $pid;
} else { // child
$func($cid);
//pcntl_waitpid(-1, $status);
exit;
}
}
public function parallel_test()
{
$func = function($id){
echo 'child ' . $id . ' starts'."\n";
$wait_time = mt_rand(1,4);
echo 'sleeping for '.$wait_time."\n";
sleep($wait_time);
echo 'child ' . $id . ' ends'."\n";
};
$children = [];
for ($i=0; $i<5; $i++){
$children[] = $this->_fork_and_exec($func) ."\n";
}
pcntl_wait($status);
echo 'done' ."\n";
exit;
}
示例输出:
child 1 starts
sleeping for 1
child 2 starts
sleeping for 1
child 3 starts
sleeping for 1
child 4 starts
sleeping for 1
child 5 starts
sleeping for 1
child 1 ends
child 2 ends
child 3 ends
child 4 ends
child 5 ends
done
预先感谢
推荐答案
这是因为所有子级都以相同的状态开始(fork()复制了代码段和数据段).而且由于rand和mt_rand是伪随机生成器,因此它们都将生成相同的序列.
That is because all children start with the same state (fork() duplicates the code and data segments). And since rand and mt_rand are pseudorandom generators, they will all generate the same sequence.
您将不得不重新初始化随机生成器,例如,使用进程/线程ID或从/dev/urandom中读取一些字节.
You will have to re-initialize the random generator, for example with the process/thread ID or read a few bytes from /dev/urandom.
这篇关于对分叉的孩子调用rand/mt_rand会产生相同的结果的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!