Calling rand/mt_rand on forked children yields identical results

前端 未结 2 835
一整个雨季
一整个雨季 2021-01-20 05:30

I\'m writing a script that needs to execute concurrent tasks in PHP.

I ran a little test and ran into strange result. I\'m using pcntl_fork to generate a child. The

相关标签:
2条回答
  • 2021-01-20 06:02

    I really think you should look at pthreads which provides multi-threading that is compatible with PHP based on Posix Threads.

    Simple as

    class AsyncOperation extends Thread {
        public function __construct($arg) {
            $this->arg = $arg;
        }
        public function run() {
            if ($this->arg) {
                echo 'child ' . $this->arg . ' starts' . "\n";
                $wait_time = mt_rand(1, 4);
                echo 'sleeping for ' . $wait_time . "\n";
                sleep($wait_time);
                echo 'child ' . $this->arg . ' ends' . "\n";
            }
        }
    }
    $t = microtime(true);
    $g = array();
    foreach(range("A","D") as $i) {
        $g[] = new AsyncOperation($i);
    }
    foreach ( $g as $t ) {
        $t->start();
    }
    

    Output

    child B starts
    sleeping for 3
    child B ends
    child C starts
    sleeping for 3
    child C ends
    child A starts
    sleeping for 4
    child A ends
    child D starts
    sleeping for 4
    child D ends
    
    0 讨论(0)
  • 2021-01-20 06:10

    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.

    You will have to re-initialize the random generator, for example with the process/thread ID or read a few bytes from /dev/urandom.

    0 讨论(0)
提交回复
热议问题