ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
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
use DBI;
use Time::Local;
use POSIX ":sys_wait_h";
$SIG{CHLD} = sub {wait ()};
#$num = "10";
my @childs;
#my $m = "mishu";
#pipe (B_IN, B_OUT);
#my $pid2 = fork();
###################### DATABASE CONNECTION #########################
my $dbName = "abc";
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);
}
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)
{
waitpid($_, WNOHANG);
}
}
print "LAST MSG ID is : ".$messageID."\n";
if($dbh->disconnect())
{
print "hello \n";
}
print "going to terminate child one \n";
#exit(0);
sub updateStatus
{
###################### DATABASE CONNECTION #########################
my $dbName = "abc";
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->disconnect();
}
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
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
Do I understand correctly that a number of children is created by your program and if all the children are alive and well then your program should iterate in some kind of loop indefinitely ?
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.
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();
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";
}
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
My point/question was: is your main program supposed to "crash" in case one of its children exits ?
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
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.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.