PHPデーモンを使用してデータベース値を取得し、取得した各IDのインスタンスを(pcntlforkを使用して)フォークします。
各フォークは何らかの作業を行ってからデータベースの値を変更するため、再度取得されることはありません。
ただし、子を fork して、たとえば 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
}
}
}
?>