pcntl_fork和MySQL连接都没了

时间:2010-09-08 14:14:09

标签: php mysql zend-framework fork

我有一个foreach循环,在其中分叉。在进程分叉之后,它访问数据库。我收到一个错误:

SQLSTATE[HY000]: General error: 2006 MySQL server has gone away

问题是,我在分叉后连接到数据库

我的问题:为什么会发生这种情况?

如果发生这种情况,我实际上是在分叉前访问数据库吗?孩子会继承数据库连接吗?

(注意:我可以发布代码,但它很大,因为它都在类中,这可能是导致我在访问数据库时的混乱。另一件事你应该知道我正在使用ZF。 )

5 个答案:

答案 0 :(得分:14)

(评论 - >根据海报的要求回答)

阅读更多内容我看到分叉的孩子继承了父母的数据库连接,这是一个众所周知的问题:http://php.net/manual/en/function.pcntl-fork.php#70721

答案 1 :(得分:6)

这对我有帮助:http://www.electrictoolbox.com/mysql-connection-php-fork/

特别是mysql_connect($server, $username, $password, true);

答案 2 :(得分:2)

除非它不是问题。这是pcntl_fork的设计方式。任何扩展(如文档明确指出)维护它自己的文件描述符都会有破坏的描述符,因为所有子节点共享相同的文件描述符。

答案 3 :(得分:1)

如果使用SIGKILL杀死分叉进程,则可以避免在分叉进程退出时关闭连接。

Unnamed

这种行为的原因是,当PHP进程退出时,PHP会向数据库服务器发送“终止连接”命令。但是只有当socket的所有链接都关闭时,socket才会被系统关闭。使用SIGKILL可以帮助我们避免向数据库服务器发送“Terminate connection”命令。

答案 4 :(得分:0)

您需要在父进程上关闭MySQL连接,然后为每个子进程建立一个新连接。

<?php
$dbh = new PDO('pgsql:host=localhost', $username, $password);
$pid = pcntl_fork();
if(!$pid){
        // make new connection
        $newConnection = new PDO('pgsql:host=localhost', $username, $password);
        // do something in the child process.
        exit;
}else{ 
        // parent node
        $dbh = null; // close PDO connection
}