in reply to Question about flock and printing to file

Hello Monks, sorry for the short question, here are some more informations:

The OS is Ubuntu 14.04, writing to the local filesystem

open ($fh, '>>', $file_out); $fh->autoflush(1); print $fh "$date;Site;CTR;IP;Temperature\n"; $i = 0; #######################Variables for the ForkManager------------------ +-------------------> my $count1 = 0; my $pm = Parallel::ForkManager->new(50); $pm->run_on_wait( sub { $count1++; }, 1 ); #<---------------------------Variables for the ForkManager############ +#################### foreach my $key_bgtr(sort keys %devices) { foreach my $key_ip (keys %{$devices{$key_bgtr}})# { $i++; $pm->start and next; $out[0]=$date.';'; $out[1]=$devices{$key_bgtr}{$key_ip}.';'; $out[2]=$key_bgtr.';'; $out[3]=$key_ip.';'; for (my $k =2;$k<=3;$k++) { if (!defined $out[$k]) {$out[$k] = './.'} } $ss = Net::SNMP->session(Hostname=> $key_ip, Timeout => 1); $out[4] = $ss->get_request(Varbindlist => [$oid]); $out[4]= $out[4]->{$oid}; if (defined $out[4] && $out[4] !~ /^$|\s/ && $out[4] >=5) { $out[4] = "$out[4]\n"; } else { $error = $ss->error(); if ($error =~ /.*noSuchName.*/) { $out[4]="no ALCplus2e\n"; } else { $out[4]="OFFLINE\n"; } print $log "$key_bgtr: $error \n"; } flock($fh, LOCK_EX) or die "cannnot lock file - $!\n"; print $fh @out; #print $fh $out[0]; #Datum #print $fh $out[1]; #Site ID #print $fh $out[2]; #BGTR/Link ID #print $fh $out[3]; #IP Adresse #print $fh $out[4]; #Temperature flock($fh, LOCK_UN) or die "cannnot unlock file - $!\n"; $ss->close; $pm->finish; } } close $fh;

The output should look like this:

"2015-06-23_16:57;124124124;123123123B;10.80.80.70;43"

But if printed value by value I sometimes get something like this:

"2015-06-23_16:57;2015-06-23_16:57;124124124;123123123B;10.80.80.70;43456456456;457457457B;10.81.81.71;43"

as if 2 forks could print to the fh, regardless of the lock on it

Replies are listed 'Best First'.
Re^2: Question about flock and printing to file
by jeffenstein (Hermit) on Jun 23, 2015 at 17:12 UTC

    From the man page of flock(2) on Linux, the file descriptors created by fork(2) are considered to be the same instance, as if you were calling flock on the same file descriptor in the same process.

    The solution would be to open the file after $pm->start, and close it before $pm->finish, so that flock(2) will consider it as a different file descriptor.

Re^2: Question about flock and printing to file
by Anonymous Monk on Jun 23, 2015 at 17:05 UTC
    as if 2 forks could print to the fh, regardless of the lock on it
    This is exactly how it works. Manpage:
    Locks created by flock() are associated with an open file table entry. This means that duplicate file descriptors (created by, for example, fork(2) or dup(2)) refer to the same lock, and this lock may be modified or released using any of these descriptors... Subsequent flock() calls on an already locked file will convert an existing lock to the new lock mode.
    If you don't understand this stuff - descriptors, file table entries - don't worry... the short answer is: yes, forks do that.