php升级后的pcntl“U分叉导致”;errno=32断管“;

php升级后的pcntl“U分叉导致”;errno=32断管“;,php,redis,upgrade,fork,pcntl,Php,Redis,Upgrade,Fork,Pcntl,我最近从PHP5.4.26升级到了5.4.28,升级后我发现了这个错误 Notice: Unknown: send of 6 bytes failed with errno=32 Broken pipe in Unknown on line 0 当我运行以下代码时: <?php $tasks = array( '1' => array(), '2' => array(), ); ini_set('display_errors', true); class

我最近从PHP5.4.26升级到了5.4.28,升级后我发现了这个错误

Notice: Unknown: send of 6 bytes failed with errno=32 Broken pipe in Unknown on line 0
当我运行以下代码时:

<?php
$tasks = array(
   '1'  => array(),
   '2'  => array(),
);

ini_set('display_errors', true);

class RedisClass {

    private $redis;

    public function __construct()
    {
        $this->redis = new Redis();
        $this->redis->connect('localhost', 6379);
    }

}

$redis = new RedisClass();

foreach ($tasks as $index => $task)
{
    $pid = pcntl_fork();

    // This is a child                                                                                                                                                          
    if($pid == 0)
    {
        echo "Running ".$index." child in ". getmypid() ."\n";
        break;
    }
}

switch($pid)
{
case -1 :
    die('could not fork');
    break;
case 0:
    // do the child code                                                                                                                                                        
    break;
default:
    while (pcntl_waitpid(0, $status) != -1)
    {
        $status = pcntl_wexitstatus($status);
        echo "Child completed with status $status\n";
    }
    echo "Child Done (says: ". getmypid() .")";
    exit;
}

这里的问题是您没有在子进程中重新连接Redis。正如迈克尔所说,从第二个孩子开始,你就没有积极的联系。如果您还进行了一些查询,那么这个mysql示例将不起作用

我在“MySQL服务器已经消失”错误和Redis中都遇到了问题


解决方案是在子系统中创建到MySQL和Redis的新连接。确保您有一个处理MySQL/Redis连接的单音来重置实例(这对我来说也是一个问题)。

我现在也在这里发布了一个问题,看看他们是否可以解释这个问题。据我所知,您所展示的MySQL示例也不应该起作用。在父进程中创建mysql连接时,所有子进程都可以使用它们。但是,当第一个子节点存在时,它会关闭与父节点的mysql连接。在PHP中分叉时要非常小心。当子进程存在时,它将关闭大多数资源(文件描述符、数据库连接、套接字)。在这方面,所有其他孩子都不能再使用这些资源了。看起来,
phpredis
php-mysql
更聪明,并且能够在分叉进程中自动重新建立连接。它在99%的情况下对我有效。不过,偶尔在高负载下我会看到这个问题。
class MysqlClass {
    private $mysqli;
    public function __construct()
    {
        $this->mysqli = mysqli_init();  //This is not the droid you are looking for                                                                                             
        $this->mysqli->real_connect('IP_ADDRESS',
                                    'USER_NAME',
                                    'PASSWORD');
    }
}

$mysql = new MysqlClass();