pcntl_fork(), MySQL, and exit()
Posted: Sun Jan 17, 2010 12:44 am
I am working on a program that forks based on certain queries from a mysql database. The program forks and when the child is done or has a problem it exits using the exit() function. This seems simple enough except that when the first child to accomplish its tasks exits, the parents link to the database goes away.
If I remove the exit command and use a posix_kill() the program continues to operate, but I get zombies.
I guess I don't fully understand the exit() function. Most of what I was able to find dealt with MySQL connection issues after the fork(). Why would an exit() in a child kill the parents connection?
Thanks
System info:
5.2.6-3ubuntu4.4
Display Errors: On
Error Level: Not E_ALL
Register Globals: Off
Enough code is supplied to illustrate the problem. After the code is the screen output.
If I remove the exit command and use a posix_kill() the program continues to operate, but I get zombies.
I guess I don't fully understand the exit() function. Most of what I was able to find dealt with MySQL connection issues after the fork(). Why would an exit() in a child kill the parents connection?
Thanks
System info:
5.2.6-3ubuntu4.4
Display Errors: On
Error Level: Not E_ALL
Register Globals: Off
Enough code is supplied to illustrate the problem. After the code is the screen output.
Code: Select all
#!/usr/bin/php -q
<?php
error_reporting(E_ALL);
/*
mysql db named test with one table named devices and the following:
U_ID LOG_DATA ACTIVE LOGGING
1 1 1 0
*/
$hostname = "localhost";
$user = "logger";
$password = "manes-69";
$db = "test";
//open db
$link = mysql_connect($hostname,$user,$password);
mysql_select_db($db, $link);
echo "mysql ".$link."\n";
// setup PID array for parent/child
$pids = array();
$x=1;
while (log_enabled($link)){
$result = mysql_query("SELECT COUNT(*) AS num FROM devices WHERE LOGGING = '1'", $link) or die();
$row = mysql_fetch_assoc($result);
$logging_count = $row['num'];
echo "logging count ".$logging_count."\n";
$result = mysql_query("SELECT COUNT(*) AS num FROM devices WHERE ACTIVE = '1'", $link) or die();
$row = mysql_fetch_assoc($result);
$active_count = $row['num'];
echo "active count ".$active_count."\n";
if ($active_count > $logging_count){ // if_1
// get active devices
$query = "select * from devices where ACTIVE = '1'";
$devsql = mysql_query($query, $link);
while ($device = mysql_fetch_assoc($devsql)){ //while_1
$pid = pcntl_fork();
if($pid == -1) {
die("could not fork");
}else if ($pid) {
// we are in the parent
$x++;
echo "PID of child ".$pid."\n";
$pids[] = $pid;
}else { // child ===============================
echo "child ".$x." \n";
sleep(15);
exit();
} // end child ===============================
}
}
sleep(4);
}
foreach($pids as $pid) {
pcntl_waitpid($pid, $status);
}
mysql_close($link);
echo "done\n";
function log_enabled($_link){
$sql = mysql_query("select * from devices where U_ID = '1'", $_link);
$settings = mysql_fetch_assoc($sql) or die(mysql_error());
if ($settings['LOG_DATA'] == 'n'){
echo "inside log enable 0 b\n";
return 0;
}
else{
echo "inside log enable 1 c\n";
return 1;
}
}
?>
~/prog/php_socket/test$ ./main.php
mysql Resource id #4
inside log enable 1 c
logging count 0
active count 1
child 1
PID of child 24191
inside log enable 1 c
logging count 0
active count 1
child 2
PID of child 24193
inside log enable 1 c
logging count 0
active count 1
child 3
PID of child 24195
inside log enable 1 c
logging count 0
active count 1
child 4
PID of child 24197
Warning: mysql_fetch_assoc(): supplied argument is not a valid MySQL result resource in /home/jcarroll/prog/php_socket/test/main.php on line 78
MySQL server has gone away