pcntl_fork 和 MySQL 连接消失

发布于 2024-09-18 18:37:09 字数 326 浏览 7 评论 0原文

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

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

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

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

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

(注意:我可以发布代码,但它相当大,因为它都在类中,这可能是导致我在访问数据库时感到困惑的原因。您应该知道的另一件事是我正在使用 ZF。)

I have a foreach loop that forks within it. After the process forks, it accesses the database. I get an error:

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

The thing is, I'm connecting to the database after I've forked.

My question: Why would this be happening?

If this happens, am I actually accessing the database before forking? Will the child inherit DB connections?

(note: I can post code, but it's rather large as it's all in classes, which could be what is causing my confusion of when I'm accessing the DB. Another thing you should know is I'm using ZF.)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

回心转意 2024-09-25 18:37:09

(评论 - >回答每个海报的请求)

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

(comment --> answer per poster's request)

Reading more into it I see forked children do inherit their parent's db connection, and it is a known problem: http://php.net/manual/en/function.pcntl-fork.php#70721

氛圍 2024-09-25 18:37:09

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

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

This helped for me: http://www.electrictoolbox.com/mysql-connection-php-fork/

Especially mysql_connect($server, $username, $password, true);

折戟 2024-09-25 18:37:09

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

<?php
$dbh = new PDO('pgsql:host=localhost', $username, $password);
$pid = pcntl_fork();
if($pid == 0){
        register_shutdown_function(function(){
                posix_kill(getmypid(), SIGKILL);
        });
        exit;
}
sleep(1);
$statement = $dbh->query('select 1');
var_dump($statement);

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

You can avoid closing connection when forked process exit, if you kill forked process with SIGKILL.

<?php
$dbh = new PDO('pgsql:host=localhost', $username, $password);
$pid = pcntl_fork();
if($pid == 0){
        register_shutdown_function(function(){
                posix_kill(getmypid(), SIGKILL);
        });
        exit;
}
sleep(1);
$statement = $dbh->query('select 1');
var_dump($statement);

The reason of this behavior, that when PHP process is exit, than PHP sends to database server "Terminate connection" command. But socket will be closed by system only when all links to socket is closed. Using SIGKILL help us to avoid sending "Terminate connection" command to database server.

吃→可爱长大的 2024-09-25 18:37:09

但这不是一个问题。这就是 pcntl_fork 的设计方式。任何维护其自己的文件描述符的扩展(如文档明确指出的那样)都会有损坏的描述符,因为所有子级和父级共享相同的文件描述符。

Except it is not a problem. It is the way pcntl_fork was designed. Any extension (as the documentation clearly states) that maintains it's own file descriptors will then have corrupted descriptors because all children an parents share the same file descriptors.

请你别敷衍 2024-09-25 18:37:09

您需要关闭父进程上的 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
}

You need to close the MySQL connection on your parent process and then make a new connection for each child.

<?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
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文