我有一个foreach循环,在其中分叉。在进程分叉之后,它访问数据库。我收到一个错误:
SQLSTATE[HY000]: General error: 2006 MySQL server has gone away
问题是,我在分叉后连接到数据库。
我的问题:为什么会发生这种情况?
如果发生这种情况,我实际上是在分叉前访问数据库吗?孩子会继承数据库连接吗?
(注意:我可以发布代码,但它很大,因为它都在类中,这可能是导致我在访问数据库时的混乱。另一件事你应该知道我正在使用ZF。 )
答案 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
}