php multiprocess script hangs after enabling grpc extension

21 views
Skip to first unread message

zheco...@gmail.com

unread,
Jul 15, 2019, 12:16:05 AM7/15/19
to grpc.io
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.

zheco...@gmail.com

unread,
Jul 16, 2019, 10:17:53 PM7/16/19
to grpc.io
Solved. See https://github.com/grpc/grpc/issues/13412

在 2019年7月15日星期一 UTC+8下午12:16:05,zheco...@gmail.com写道:
Reply all
Reply to author
Forward
0 new messages