Hi all,

Our application experienced a annoying problem. When enabling grpc.so 
extension, php script with multiprocess hangs even we don't use any grpc 
api.

This is reproducible code. I can reproduce it in PHP 5.6 and PHP 7.1. After 
disable grpc.so extension, it can exit normally.

<?php

    function startWith($str, $prefix) {
        if (strlen($prefix) > strlen($str)) {
            return false;
        }

        return substr($str, 0, strlen($prefix)) === $prefix;
    }
    /**
     * @param     $daemonName    string
     * @param     $callback      callback 
     * @param     $processAmount int
     * @param     $timeOut       if it's not zero, child process will exit 
after $timeOut seconds
     */
    function restartDaemons($daemonName, $callback, $processAmount = 1, 
$timeOut = 0)
    {
        $daemonName = strtolower($daemonName);
        // control child processes via file existence
        $pidDir = RUNTIME_PATH . DIRECTORY_SEPARATOR . 'pid';
        if (!is_dir($pidDir)) {
            mkdir($pidDir, 0777, true);
        }
        //clear pid files
        $pidDirHandle = opendir($pidDir);
        while ($fileName = readdir($pidDirHandle)) {
            if (startWith($fileName, $daemonName . '.worker.')) {
                @unlink($pidDir . DIRECTORY_SEPARATOR . $fileName);
                echo 'CLEAN_PID_FILE' . "\n";
            }
        }

        for ($i = 0; $i < $processAmount; $i++) {
            $pid = pcntl_fork();
            if ($pid == 0) {
                //child processe logic
                $pid     = getmypid();
                $pidFile = $pidDir . DIRECTORY_SEPARATOR . $daemonName . 
'.worker.' . $pid;

                touch($pidFile);
                echo "worker start: " . ($i + 1) . "/$processAmount" . 
PHP_EOL;
                $startDaemonTime[$i] = microtime(true);
                while (file_exists($pidFile)) {
                    if($timeOut > 0 && microtime(true) - 
$startDaemonTime[$i]  > $timeOut){
                        break;
                    }
                    $roundStartTime = microtime(true);
                    $runSuccess     = $callback($processAmount, $i);
                    if (!$runSuccess) {
                        sleep(1);
                    } else {
                    }
                }
                echo "worker exit: " . ($i + 1) . "/$processAmount" . 
PHP_EOL;
                exit(0);
            }
        }
        //parent process waits for child processes
        for ($i = 0; $i < $processAmount; $i++) {
            $spId = pcntl_wait($status);
            if ($status != 0) {
            }
        }
    }

restartDaemons('haha', function() {return true;}, 10, 10);


I use strace to see what's last system call, this is output

[root@c3d1d6a011ac /]# strace -p 209
Process 209 attached
futex(0x7fe261ffb764, FUTEX_WAIT_PRIVATE, 1, NULL

Please help me. Guide me to some debug approaches or something.

Thanks.

-- 
You received this message because you are subscribed to the Google Groups 
"grpc.io" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/grpc-io/a68c0838-2b31-450b-8a83-8c0dcd66c8b3%40googlegroups.com.

Reply via email to