perl crashing after doing some fork()
Hello everyone,
I have a perl program that does the following thing: 1. Continuously looking in a mysql database table for a row that has status '2'. 2. If a status 2 row is found it first checks whether that particular row has been previously visited or not. 3. If not previously visited it will create a child process. 4. The parent again enters the loop and look for any new status '2'. 5. In the mean time the child process waits for 10 sec and updates the row status to 7 if the status of that row is still remaining as '2'. This program works fine for sometime but after some time it simply crashes. Can you please help me out!!!! Here is my code: Code:
#!/usr/bin/perl Thanks Mishu |
First add
Code:
use strict; Code:
#!/usr/bin/perl The word "crashes" is not clear in this context - what is the exact error message ? |
Actually there is no error message. you can see that i am running an infinite while loop. So it is not supposed to stop. But it stops after some time. I am using the word "Perl crashing". Because before stopping a windows prompt appears saying "perl.exe Application error. The instruction at '0x.........' referenced memory at '0x........' The memory could not be read."
There is also another error saying "DESTROY ignored because DBI sth handle (DBD::mysql::st) is owned by thread 2 33fac not current thread 45ad004" But this error msg does not come all the time Please help me out guys Mishu |
Quote:
|
Thank you Seregi for your reply. Actually I am iterating in an infinite while loop where i am checking in the database table for status '2' and if i find any new entry i simply fork. In the child process it waits for 10 sec and after 10 sec it calls a function 'updateStatus' which simply updates the status '2' to '7'(if the status is still 2). Parallely the parent process will go in the loop again and check if there is any new row inserted with status '2'.
Basically I am trying to make a timer function that will keep track of any new row being inserted in the DB and after a certain time later, it will update that row. Thanks Mishu |
actually I have just updated the code a bit. Please have a look guys:
<code> #!/usr/bin/perl use DBI; use Time::Local; use POSIX ":sys_wait_h"; use warnings; $SIG{CHLD} = sub {wait ()}; my @childs; ###################### DATABASE CONNECTION ######################### my $dbName = "middleware"; my $userName = "root"; my $password = ""; my $dbpath = "dbi:mysql:database=$dbName;host=localhost"; my $dbh = DBI->connect($dbpath, $userName, $password) or die "Can't open database: $DBI::errstr"; ##################################################################### my %alreadyVisited; my $messageID; while(1) { my $query = "SELECT * FROM `transaction_log` WHERE status = '2'"; my $qh = $dbh->prepare($query); $qh->execute(); while(my $row = $qh->fetchrow_hashref()) { $messageID = $row->{message_id}; if(exists $alreadyVisited{$messageID}) { #print $messageID." already exists in HASH \n"; next; } else { #print $messageID." is a new one \n"; } my $pid = fork(); if($pid) { #parent #print "Child created with PID : ".$pid."\n"; push(@childs, $pid."~".$messageID); } elsif($pid == 0) { #child print $messageID." is in child\n"; sleep(10); updateStatus($messageID); #print "%%%%%%%%%%%%%%%%%%%%%%%%%% \n"; exit(0); } else { print "Could not fork \n"; } $alreadyVisited{$messageID} = $row->{name}; } sleep(1); foreach (@childs) { print "**".$_."**\n"; if($_ ne "") { my @pidArray = split('~', $_); my $pid = $pidArray[0]; my $mid = $pidArray[1]; #print $pid." ".$mid."++++\n\n"; if(waitpid($pid, WNOHANG) eq $pid) { my $element = $pid."~".$mid; my( $index )= grep { $childs[$_] eq $element } 0..$#childs; splice(@childs, $index, 1); } } } } print "LAST MSG ID is : ".$messageID."\n"; if($dbh->disconnect()) { print "hello \n"; } print "going to terminate child one \n"; sub updateStatus { ###################### DATABASE CONNECTION ######################### my $dbName = "middleware"; my $userName = "root"; my $password = ""; my $dbpath = "dbi:mysql:database=$dbName;host=localhost"; my $dbh2 = DBI->connect($dbpath, $userName, $password) or die "Can't open database: $DBI::errstr"; ##################################################################### my $ID = $_[0]; print $ID."****\n"; my $query2 = "UPDATE `transaction_log` SET status = '7' WHERE status = '2' AND message_id = '".$ID."'"; my $qh2 = $dbh2->prepare($query2); if($qh2->execute() eq 1) { print $ID." has been updated to 7\n"; } else { print "Failed to update ID is : ".$ID."\n"; } #$dbh2->commit; $dbh2->disconnect(); } </code> thnx mishu |
Quote:
If yes, maybe you should check what is happening with(in) each child ? |
No my main program is not supposed to crash. Every time a child is created it will exit after 10 sec(by doing/not doing a update in DB) anyway. The child programs that are being created are doing their job(updating row) properly as long its running fine. May be I am doing something wrong regarding creating child or something. I cant find a clue what actually is the problem that is actually causing a crash.
Thanks man mishu |
I think you still don't have
Code:
use strict; |
i tried using strict but its causing the same problem.
|
hello everyone, I am still facing the same problem. Please help me out guys. My project deadline is 2 days from now. I have to find some solution.
Thanks mishu |
Since your program is apparently running under Windows, this may not apply, but if you are constantly spawning child processes without calling wait() to reap them, it seems possible that you are filling the process table (or whatever is equivalent under Windows). In Unixish OS's this is the standard paradigm to prevent zombie processes.
--- rod. |
All times are GMT -5. The time now is 12:31 PM. |