} } echo "Master main EP " . getmypid() . "\n"; $criticalSection = new GPhpThreadCriticalSection(); $criticalSection->cleanPipeGarbage(); // remove any garbage left from any ungracefully terminated previous executions $threadPool = array(); $tpSize = 20; for ($i = 1; $i <= $tpSize; ++$i) { $threadPool[$i] = new MyThread($criticalSection, true); } // xhprof_enable(XHPROF_FLAGS_CPU + XHPROF_FLAGS_NO_BUILTINS); GPhpThread::BGN_HIGH_PRIOR_EXEC_BLOCK(); // this will result fast thread creation but, because of that all threads will try // to reach the critical section at once in some cases may take twice the time for each one in order to lock the critical section for ($i = 1; $i <= $tpSize; ++$i) { $threadPool[$i]->start(); echo "{$i} of {$tpSize} started\n"; } GPhpThread::END_HIGH_PRIOR_EXEC_BLOCK(); for ($i = 1; $i <= $tpSize; ++$i) { $threadPool[$i]->join(); } // $xhprof_data = xhprof_disable(); echo "\n\n---The last writing in the critical section was done by thread---\n"; echo "---" . $criticalSection->getResourceValueFast('IAM') . "\n\n"; //uasort($xhprof_data, function ($a, $b) { // if ($a['wt'] > $b['wt']) return -1; // else return 1; //}); // print_r($xhprof_data);
/** * Waits for executing thread to return. * @param bool $useBlocking If is set to true will block the until the thread returns. * @return bool True if the thread has joined otherwise false. */ public final function join($useBlocking = true) { // {{{ if (!$this->amIStarted) { return false; } if ($this->amIParent()) { $status = null; $res = 0; if ($useBlocking) { GPhpThread::BGN_HIGH_PRIOR_EXEC_BLOCK(); while (($res = pcntl_waitpid($this->childPid, $status, WNOHANG)) == 0) { GPhpThreadCriticalSection::dispatch(); usleep(mt_rand(10000, 40000)); } if ($res > 0 && pcntl_wifexited($status)) { $this->exitCode = pcntl_wexitstatus($status); } else { $this->exitCode = false; } if ($this->criticalSection !== null) { $this->criticalSection->finalize($this->uniqueId); } $this->childPid = null; $this->_childPid = null; $this->amIStarted = false; GPhpThread::END_HIGH_PRIOR_EXEC_BLOCK(); } else { $res = pcntl_waitpid($this->childPid, $status, WNOHANG); if ($res > 0 && $this->criticalSection !== null) { $this->criticalSection->finalize($this->uniqueId); } if ($res > 0 && pcntl_wifexited($status)) { $this->exitCode = pcntl_wexitstatus($status); if ($this->criticalSection !== null) { $this->criticalSection->finalize($this->uniqueId); } $this->amIStarted = false; } else { if ($res == -1) { $this->exitCode = false; } } if ($res != 0) { if ($this->criticalSection !== null) { $this->criticalSection->finalize($this->uniqueId); } $this->childPid = null; $this->_childPid = null; } } return $res; } if ($this->childPid == -1) { return false; } exit(255); }