pcntl_signal(SIGTERM, "sig_handler");
function sig_handler($signo) {
switch($signo) {
case SIGTERM:
// handle shutdown tasks
syslog(LOG_INFO, "CAUGHT SIGTERM. Closing up shop and going home.");
syslog(LOG_INFO, "Complete");
closelog();
exit;
break;
case SIGHUP:
// handle restart tasks
break;
case SIGUSR1:
print "Caught SIGUSR1...\n";
break;
default:
// handle all other signals
}
}
***********************************
Creating a daemon with php and fork.
***********************************
<?php
declare(ticks=1);
$pid = pcntl_fork();
if ($pid == -1) {
die("could not fork");
} else if ($pid) {
exit(); // we are the parent
} else {
// we are the child
}
// detatch from the controlling terminal
if (!posix_setsid()) {
die("could not detach from terminal");
}
// setup signal handlers
pcntl_signal(SIGTERM, "sig_handler");
pcntl_signal(SIGHUP, "sig_handler");
// loop forever performing tasks
while(1) {
// do something interesting here
}
function sig_handler($signo) {
switch($signo) {
case SIGTERM:
// handle shutdown tasks
exit;
break;
case SIGHUP:
// handle restart tasks
break;
default:
// handle all other signals
}
}
?>
*******************************************************************************
* Here's an example of how to get data back from the child. That's the missing
* piece.
*******************************************************************************
You can use IPC to achieve just that. Every child that is spawned has to tell its parent that time has come for him to be terminated. So, yes, zombies will be created, but once in a while the parent will 'clean up' after his kids. Code:
<?php
declare(ticks = 1);
// create a IPC message queue
$msgqueue = msg_get_queue(ftok("/tmp/php_msgqueue.stat", 'R'),0666 | IPC_CREAT);
// loop for 1000 children
for ($c = 0; $c < 1000; $c++) {
// fork
$pcid = pcntl_fork();
if ($pcid == -1) {
die("Could not fork!");
}
elseif ($pcid) { // we are the parent, look for zombie kids and terminate 'em
// look in the IPC message queue if there are any entries
$currentqueue = msg_stat_queue($msgqueue);
$n = $currentqueue['msg_qnum']; // number of messages (number of kids to terminate)
if ($n > 0) {
echo "There are $n kids to terminate.\n";
for ($i = 0; $i < $n; $i++) {
// pop the kid's PID from the IPC message queue
if (!msg_receive ($msgqueue, 1, $msg_type, 16384, $msg, true, 0, $msg_error)) {
echo "MSG_RECV ERROR: $errmsg \n"; // something has gone wrong
}
else {
pcntl_waitpid($msg, $tmpstat, 0); // terminate kid for real.
};
};
};
}
else { // we are the child!
if (!posix_setsid()) { die ("Could not detach"); }; // detach
echo "I am child number $c\n";
sleep(5); // do something useful
// tell dad I'm finished via IPC: send him my PID
if (!msg_send($msgqueue, 1, posix_getpid(), true, true, $errmsg)) {
echo "MSG_SEND ERROR: $errmsg \n";
};
exit(); // become a zombie until dad kills me
};
};
?>