众所周知,当您 fork 时,孩子会获得所有内容的副本,包括文件和网络描述符 - man fork
.
在 PHP 中,当您使用 pcntl_fork 时,您使用 mysql_connect 创建的所有连接都会被复制,这有点问题 - php docs and SO question。这种情况下的常识是关闭父连接,创建新连接并让孩子使用旧连接。但是,如果说父母需要在几秒钟内创造出许多孩子呢?在这种情况下,您最终会创建大量新连接 - 每一堆叉子都有一个。
这在代码中意味着什么:
while (42) {
$db = mysql_connect($host, $user, $pass);
// do some stuff with $db
// ...
foreach ($jobs as $job) {
if (($pid = pcntl_fork()) == -1) {
continue;
} else if ($pid) {
continue;
}
fork_for_job($job);
}
mysql_close($db);
wait_children();
sleep(5);
}
function fork_for_job($job) {
// do something.
// does not use the global $db
// ...
exit(0);
}
好吧,我不想那样做——这对数据库的连接太多了。理想情况下,我希望能够实现与此类似的行为:
$db = mysql_connect($host, $user, $pass);
while (42) {
// do some stuff with $db
// ...
foreach ($jobs as $job) {
if (($pid = pcntl_fork()) == -1) {
continue;
} else if ($pid) {
continue;
}
fork_for_job($job);
}
wait_children();
sleep(5);
}
function fork_for_job($job) {
// do something
// does not use the global $db
// ...
exit(0);
}
你认为有可能吗?
其他一些事情:
- 这是 php-cli 脚本
我已经尝试在第一个示例中使用 mysql_pconnect,但据我所知没有区别 - mysql 服务器接收到尽可能多的新连接。也许那是因为它是 cli 并且 pconnect 不能像在 mod_php 中那样工作。正如 Marc 所注意到的 - php-cli 中的 pconnect 没有意义。