X
xargle
I'm using perl 5.8.5 under RHEL 4, and trying to produce a quick
sockets server with 240 forked processes all accepting from a listener
socket. Which fork gets to accept is governed by who gets the flock,
which would normally be a flock on the listener socket, but as that
didn't work I tried using a file in /tmp and flocking that. This is
apparently what apache does. This is an attempt at optimising an
existing application to reduce load as connections to the server are
very short and very regular, so the constant forking is undesirable...
my $kid;
my $socket = IO::Socket::INET->new(
LocalPort => '4576',
Proto => 'tcp',
Listen => SOMAXCONN,
Reuse => 1)
or die "Failed to listen: $!";
my $i=0;
# ignore the kids, they're noisy little gits
$SIG{CHLD} = 'IGNORE';
# open a temp file to provide us with a locking mechanism as
# perl doesn't appear to like us locking socket handles
sysopen(LOCKFILE, "/tmp/test.lock", O_WRONLY | O_CREAT) || die "Can't
open lock file /tmp/test.lock\n";
STDOUT->autoflush(1);
while ($i < $tofork)
{
sleep 1;
$i++;
# fork here, if we're the parent just loop
next if $kid = fork;
print STDOUT "Forked worker on pid " . getpid() . "\n";
while(1)
{
print STDOUT getpid() . " requesting LOCK_EX\n";
flock LOCKFILE,2 or die "cant flock: $!"; # 2 = LOCK_EX, exclusive
lock
print STDOUT getpid() . " has gained LOCK_EX\n";
my $client = $socket->accept();
print STDOUT getpid() . " accepted connection from " .
$client->sockhost . " and will unlock listener\n";
flock LOCKFILE,8 or die "cant flock: $!"; # 8 = LOCK_UN, unlock
process_connection($client);
print STDOUT getpid() . " session is done\n";
}
while(1)
{
sleep(60);
}
}
The while(1) sleep is a desperate measure whilst attempting to get the
locking working in case the parent thread exiting was the issue, ditto
the sleep 1 between starting the threads.
What happens is the 240 threads start, but the flock LOCK_EX (2)
doesn't block at all and returns no error, so all the forks end up
trying to accept which is precisely what I don't want to occur.
Am I missing something here? Does flock work in 5.8.5? Is it something
to do with the forking?
Any advice would be greatly appreciated.
sockets server with 240 forked processes all accepting from a listener
socket. Which fork gets to accept is governed by who gets the flock,
which would normally be a flock on the listener socket, but as that
didn't work I tried using a file in /tmp and flocking that. This is
apparently what apache does. This is an attempt at optimising an
existing application to reduce load as connections to the server are
very short and very regular, so the constant forking is undesirable...
From the entry point the code looks like this :
my $kid;
my $socket = IO::Socket::INET->new(
LocalPort => '4576',
Proto => 'tcp',
Listen => SOMAXCONN,
Reuse => 1)
or die "Failed to listen: $!";
my $i=0;
# ignore the kids, they're noisy little gits
$SIG{CHLD} = 'IGNORE';
# open a temp file to provide us with a locking mechanism as
# perl doesn't appear to like us locking socket handles
sysopen(LOCKFILE, "/tmp/test.lock", O_WRONLY | O_CREAT) || die "Can't
open lock file /tmp/test.lock\n";
STDOUT->autoflush(1);
while ($i < $tofork)
{
sleep 1;
$i++;
# fork here, if we're the parent just loop
next if $kid = fork;
print STDOUT "Forked worker on pid " . getpid() . "\n";
while(1)
{
print STDOUT getpid() . " requesting LOCK_EX\n";
flock LOCKFILE,2 or die "cant flock: $!"; # 2 = LOCK_EX, exclusive
lock
print STDOUT getpid() . " has gained LOCK_EX\n";
my $client = $socket->accept();
print STDOUT getpid() . " accepted connection from " .
$client->sockhost . " and will unlock listener\n";
flock LOCKFILE,8 or die "cant flock: $!"; # 8 = LOCK_UN, unlock
process_connection($client);
print STDOUT getpid() . " session is done\n";
}
while(1)
{
sleep(60);
}
}
The while(1) sleep is a desperate measure whilst attempting to get the
locking working in case the parent thread exiting was the issue, ditto
the sleep 1 between starting the threads.
What happens is the 240 threads start, but the flock LOCK_EX (2)
doesn't block at all and returns no error, so all the forks end up
trying to accept which is precisely what I don't want to occur.
Am I missing something here? Does flock work in 5.8.5? Is it something
to do with the forking?
Any advice would be greatly appreciated.