Updated September 5, 2016: Modified code to run with MCE 1.8 / MCE::Shared 1.8.
The following runs with Perl not built with threads support.
use strict;
use warnings;
# usage: ./collect_files.pl <user> /var/tmp /tmp
# output is saved under /var/tmp/test_<user>.file.list
use File::Spec::Functions qw(catfile);
use MCE;
use MCE::Queue;
use MCE::Shared;
# Get user info and directories to start with
my $user = shift;
my $uidNum = getpwnam($user);
my @start_dirs = @ARGV
or die "Please specify one or more starting directories, stopped";
-d or die "No such directory: $_, stopped" for @start_dirs;
# Shared queue and counter
my $shared_work = MCE::Queue->new( fast => 1, queue => \@start_dirs );
my $free_count = MCE::Shared->scalar( 0 );
# Open output file
open my $user_file, ">", "/var/tmp/test_$user.file.list"
or die "cannot open file: $!";
sub traverse {
$free_count->decr;
my ( $dev, $ino, $mode, $nlink, $uid, $gid );
my @work = $_;
while ( $_ = shift @work, defined ) {
my ( $dir, $path, @paths ) = ( $_ );
opendir DH, $dir or next;
for ( readdir DH ) {
next if $_ eq '.' || $_ eq '..';
if ( -d ( $path = catfile($dir,$_) ) ) {
( @work < 15 )
? push @work, $path
: $shared_work->enqueue($path);
next;
}
push @paths, $path;
}
for my $file ( @paths ) {
if ( -f $file ) {
( $dev, $ino, $mode, $nlink, $uid, $gid ) = lstat( $file )
+;
MCE->print( $user_file, "$file:$uidNum:$gid:$mode\n" )
if $uid == $uidNum;
}
}
}
# Done with our work, let everyone know we're free
$shared_work->enqueue( (undef) x MCE->max_workers )
if $free_count->incr == MCE->max_workers && !$shared_work->pendi
+ng;
}
my $mce = MCE->new(
max_workers => 8,
user_begin => sub { $free_count->incr },
user_func => sub { traverse() while ($_ = $shared_work->dequeue, de
+fined) },
);
$mce->run;
close $user_file;
Kind regards, Mario