D
dede
Dear community,
having written a working example for using Semphores on a windows
client, I created a little "server-application" that does the following:
A Server continously "listens/tails" a command-file for new commands.
If a new commands arrives a split of the workload to threads is under-
taken that "control themselves" via Semaphore and are joined finally.
It works.
However, the aspects of logging "I am done" into a log-file does
mysteriously not work synchronised although:
- all threads are definitely joined (see below)
- autoflush is active ($|=1
What I observe NOW (see code below) is that the new log-line is written
when a further command arrives OR when the server is interrupted.
Any ideas are highly appreciated. THank you in advance.
Andreas, Paris / France
#----------------------------------------------------------------
use threads;
use Win32::Semaphore;
#replaces the http://www.perldoc.com/perl5.8.0/pod/perlthrtut.html
# example of Semaphore (for UNIX)
my $endFlag = undef;
my $logFile = 'D:/www/eclipse/workspace/Perltest/status.log';
my $cmdFile = 'D:/www/eclipse/workspace/Perltest/cmd.log';
my $noThreads = 2; #two threads work at the same time
my $noTasks = 8; #our static workload is 8 tasks
$|=1; #autoflush
open (CMD, "<$cmdFile") || die "error in open:$!";
#seek Handle, Offset_in_bytes, Whence (0=start, 1=cursor, 2=EOF)
seek CMD, 0, 2; #wait at end of file for new incoming commands
open (LOG, ">>$logFile") || die "error in open:$!";
# ">>" positions already automatically to EOF
#note that the position of the sig-handler routine is important !!
$SIG{INT} = sub { print "\n time to say goodbye!\n";
$endFlag = 1; };
while (!defined $endFlag) {
while (<CMD>) {
print "New Command: $_\n";
processCmd($_);
} #while
print "sleeping for some seconds\n";
sleep 5;
#magic "hopping on the same spot" / Huepfen auf der Stelle
seek CMD, 0, 1; #reposition to "cursor" -> clear EOF-Flag
}#for
sub processCmd {
my $para = shift; #para is the command of CMD-file
print LOG "Processing $para"; #write some useful log-info
@th = (); #initialize array of threads
my $s = Win32::Semaphore->new($noThreads,$noThreads);
#We generate all threads
for (1..$noTasks) {
push @th, threads->new(\&myThread, $_, $s);
}
#..and join them afterwards
for (0..($noTasks - 1)) {
print "join task $_...";
$th[$_]->join();
print "done\n";
}
#xxxxxxxxxx - this log-entry is only written
#xxxxxxxxxx ..after we start the next command OR
#xxxxxxxxxx ..the server is stopped by CTRL-C (INT)
print LOG "Finished $para";
} #sub
# just another dummy thread to do some time-consuming stuff
sub myThread {
my ($p, $s) = @_;
$s->wait();
$w = int (rand($p)/3) + 2;
print "i am a thread $p wait for $w seconds\n";
sleep $w;
$s->release();
} #sub
1;
#----------------------------------------------------------------
having written a working example for using Semphores on a windows
client, I created a little "server-application" that does the following:
A Server continously "listens/tails" a command-file for new commands.
If a new commands arrives a split of the workload to threads is under-
taken that "control themselves" via Semaphore and are joined finally.
It works.
However, the aspects of logging "I am done" into a log-file does
mysteriously not work synchronised although:
- all threads are definitely joined (see below)
- autoflush is active ($|=1
What I observe NOW (see code below) is that the new log-line is written
when a further command arrives OR when the server is interrupted.
Any ideas are highly appreciated. THank you in advance.
Andreas, Paris / France
#----------------------------------------------------------------
use threads;
use Win32::Semaphore;
#replaces the http://www.perldoc.com/perl5.8.0/pod/perlthrtut.html
# example of Semaphore (for UNIX)
my $endFlag = undef;
my $logFile = 'D:/www/eclipse/workspace/Perltest/status.log';
my $cmdFile = 'D:/www/eclipse/workspace/Perltest/cmd.log';
my $noThreads = 2; #two threads work at the same time
my $noTasks = 8; #our static workload is 8 tasks
$|=1; #autoflush
open (CMD, "<$cmdFile") || die "error in open:$!";
#seek Handle, Offset_in_bytes, Whence (0=start, 1=cursor, 2=EOF)
seek CMD, 0, 2; #wait at end of file for new incoming commands
open (LOG, ">>$logFile") || die "error in open:$!";
# ">>" positions already automatically to EOF
#note that the position of the sig-handler routine is important !!
$SIG{INT} = sub { print "\n time to say goodbye!\n";
$endFlag = 1; };
while (!defined $endFlag) {
while (<CMD>) {
print "New Command: $_\n";
processCmd($_);
} #while
print "sleeping for some seconds\n";
sleep 5;
#magic "hopping on the same spot" / Huepfen auf der Stelle
seek CMD, 0, 1; #reposition to "cursor" -> clear EOF-Flag
}#for
sub processCmd {
my $para = shift; #para is the command of CMD-file
print LOG "Processing $para"; #write some useful log-info
@th = (); #initialize array of threads
my $s = Win32::Semaphore->new($noThreads,$noThreads);
#We generate all threads
for (1..$noTasks) {
push @th, threads->new(\&myThread, $_, $s);
}
#..and join them afterwards
for (0..($noTasks - 1)) {
print "join task $_...";
$th[$_]->join();
print "done\n";
}
#xxxxxxxxxx - this log-entry is only written
#xxxxxxxxxx ..after we start the next command OR
#xxxxxxxxxx ..the server is stopped by CTRL-C (INT)
print LOG "Finished $para";
} #sub
# just another dummy thread to do some time-consuming stuff
sub myThread {
my ($p, $s) = @_;
$s->wait();
$w = int (rand($p)/3) + 2;
print "i am a thread $p wait for $w seconds\n";
sleep $w;
$s->release();
} #sub
1;
#----------------------------------------------------------------