I'm having a torrid time with File::Temp. I like the module and it works mostly well, but I'm not doing something correctly with it.
In an Apache/mod_Perl PerlRun applicatiion I have the following happening many times:
{ # start scope ($SFH, $softer) = tempfile(SUFFIX => ".data", DIR => "/tmp/", UNLINK => 1); ... stuff ... unlink0 ($SFH, $softer); } # end scope
This appears to works on Windows (Perl 5.6.1, Apache 1.3.26, File::Temp 0.12), without a problem, I don't run out of file handles, and I don't have files left over, but Windows isn't used as much. On the Linux box, same spec, much higher load levels, I've had miserable problems.
As far as I can tell it's simply confused because it's running under mod_Perl, and the Perl processor never ends, so the normal end of Perl clean up isn't happening. The way I would expect.
Trying to find out how many file handles a Linux system can or cannot have hasn't been easy either. I've done quite a bit of Goolging, but there the same thing out there many times, but so far I've not discovered any deep magic.
For example on two nearly identical RedHat 7.x systems cat /proc/sys/fs/file-nr
gives:
It took me a long time to figure out that the middle number is the number of free, not the number of used file handles, and hence a small number is bad.
From
The kernel allocates file handles dynamically, but as yet it doesn't free them again. The value in file-max denotes the maximum number of file- handles that the Linux kernel will allocate. When you get lots of error messages about running out of file handles, you might want to increase this limit. The three values in file-nr denote the number of allocated file handles, the number of used file handles and the maximum number of file handles. When the allocated file handles come close to the maximum, but the number of actually used ones is far behind, you've encountered a peak in your usage of file handles and you don't need to increase the maximum.
-Dom
What happens if you put a close $fh in there before you leave the routine?
-Dom
Re:tempfile
ajt on 2003-02-28T14:59:37
Dom2,
Useful comments. I agree it's a great module, the problem started when I was working with it on NT and Linux. When I'd finished NT was working okay, but Linux was not....
If you have an explicit
close $fh
, then what I found was that the file was NOT deleted, and I can't remember if the file handle was. I've even tried an explicitunlink
too.Like I said I feel part of the problem is that it's running under mod_perl PerlRun, which is a bit of an odd place!
Since I posted, I'm now at: 8192, 2781, 16384 on the problem box. I had over 6000 free file handles this morning, before people came in to use the web server.
Re:tempfile
Dom2 on 2003-02-28T16:55:40
As I said in the first reply, I don't necessarily think those kernel figures are anything to worry about. But I would be concerned about the undeleted files.The docs state that a file is not auto deleted, if a filehandle is requested as well as a filename. You have to unlink it yourself.
One more thing; You might wish to check whether or not the unlink fails: unlink( $fname ) or warn "unlink($fname): $!\n"
Oh, and to see whether filehandles are leaking in real, useful terms, the best thing to do is run "lsof -p" on the pid of the web server. That's more useful than the system-wide kernel measurements.
I suppose that at worst, you just write a cron job to clean them...
-Dom
Re:tempfile
ajt on 2003-03-01T12:32:02
Dom,
I think I know what is going on! I created the following little script, popped it into my PerlRun folder on my home Linux box and tested all the permutations.
#!/usr/bin/perl
$|++;
use strict;
use CGI;
use File::Temp qw(tempfile unlink0);
my $q = CGI->new;
print $q->header(-type => "text/plain");
print "PID: $$\n";
print `cat/proc/sys/fs/file-nr`;
for (1..50) {
my ($TMP_FH, $tmp_file) = tempfile(SUFFIX => ".f", UNLINK => 0);
print "Created: $tmp_file\t";
print `cat/proc/sys/fs/file-nr`;
unlink0 ($TMP_FH, $tmp_file);
close $TMP_FH;
}What I found was that with
UNLINK=>1
on, my Linux box wasn't releasing file handles until the parent Apache process was terminated. I'd turned this on to get round files that were not being removed on NT (I thought at the time - though I may now be wrong).With
UNLINK=>0
, if I do an explicit close of the filehandle, or let it go out of scope then I'm okay with file handles, but not files, they get left over.Most recently I tried the
unlink0
option that comes with File::Temp, it should be smarter and more secure than a plainunlink
. WithUNLINK=>1
it doesn't work, but withUNLINK=>0
it removes the files, and the file-handles are returned to the system.My elderly RedHat 6 system didn't have lsof on it, so I went off and found it and built it - seems a useful tool.