Как вы все знаете, когда вы разветвляете, дочерний элемент получает копию всего, включая файловые и сетевые дескрипторы — man fork
.
В PHP, когда вы используете pcntl_fork, все ваши соединения, созданные с помощью mysql_connect, копируются, и это некоторая проблема - php docs и SO вопрос. Здравый смысл в этой ситуации говорит закрыть родительское соединение, создать новое и позволить дочернему использовать старое. Но что, если указанному родителю нужно создавать много детей каждые несколько секунд? В этом случае вы в конечном итоге создадите множество новых подключений — по одному на каждый набор ответвлений.
Что это означает в коде:
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.Как заметил Марк - pconnect в php-cli не имеет смысла.