gpt4 book ai didi

php - PHP 守护进程中的 "MySQL gone away",使用 pcntl_fork

转载 作者:行者123 更新时间:2023-11-29 05:21:03 26 4
gpt4 key购买 nike

我正在尝试使用 PHP 守护程序检索数据库值,并为检索到的每个 ID fork (使用 pcntlfork)一个实例。

每个 fork 都应该做一些工作然后改变数据库值,所以它不会被再次检索。

但是,当我 fork 一个 child 并让它休眠 10 秒(例如实际处理时间)时,MySQL 连接似乎超时了。我如何防止这种情况发生? try/catch 似乎无法阻止错误。

#!/usr/bin/php
<?php
ini_set('memory_limit','256M');
gc_enable();

function sig_handler($signo) {
global $child;
switch ($signo) {
case SIGCHLD:
echo "SIGCHLD received\n";
$child--;
}
}

// install signal handler for dead kids
pcntl_signal(SIGCHLD, "sig_handler");

global $PIDS; $PIDS = array();
global $maxforks; $maxforks = 5;
global $child; $child = 1;

global $boot; $boot = true;
date_default_timezone_set('Europe/Brussels');

// figure command line arguments
if($argc > 0){
foreach($argv as $arg){
$args = explode('=',$arg);
switch($args[0]){
case '--log':
$log = $args[1];
break;
case '--msgtype':
$msgtype = $args[1];
break;
} //end switch
} //end foreach
} //end if

// Daemonizen
$daemon_start = date('j/n/y H:i', time());
$pid = pcntl_fork();
if($pid == -1){
return 1; // error
} else if($pid) {
return 0;
} else {
while(true){

try {
$host = 'localhost';
$dbname = 'bla';
$dbuser = 'bla';
$dbpass = 'bla';
$db = new PDO('mysql:host='.$host.';dbname='.$dbname.';charset=utf8', $dbuser, $dbpass, array(PDO::ATTR_TIMEOUT => 2));
//$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING);
} catch (PDOException $e){
echo $e->getMessage();
}

$read_messages = $db->query("SELECT * blablabla");
while($read_message_row = $read_messages->fetch(PDO::FETCH_ASSOC)){
$id = $read_message_row['id'];

$pid1 = pcntl_fork();
if ($pid1 == -1){
die('could not fork');
} else { #START ELSE COULD FORK
$PIDS[$pid1] = $pid1; //KEEP TRACK OF SPAWNED PIDS
if ($pid1){
// parent
if ($child++ >= $maxforks){
pcntl_wait($status);
$child++;
}

echo "Forking child with PID $pid1 voor $id.\n";

//PARENT THREAD : $ch is a copy that we don't need in this thread
// child forken
} else {
include_once "test_worker.php";
} // einde child thread
} //if-else-forked


}
}
}
?>

最佳答案

解决方法很简单。 fork 后连接(或重新连接)。

fork 进程是其父进程的精确镜像并共享资源句柄。当您的 fork 进程之一关闭数据库连接时,树中的所有其他进程都会关闭它 - 即使在查询中间。然后您会收到诸如“MySQL 服务器已消失”或“查询期间与 MySQL 服务器失去连接”之类的错误。

关于php - PHP 守护进程中的 "MySQL gone away",使用 pcntl_fork,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25753079/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com