Perl多线程程序 [英] Perl Multithread Program

查看:66
本文介绍了Perl多线程程序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是Perl的新手.我想用线程写一个Perl脚本,我只有几个文件说20个文件,并且想用4个批处理的5个线程来处理这些文件.我正在打印线程号.完成一个批次后,下一个批次的线程号必须以1开头.但是与其创建20个线程,请帮助.我的代码如下:

I am new in Perl. I want to write a Perl script using thread.I have few files say 20 files and want to process those files using 5 threads in 4 batches. I am printing the thread no. After completing one batch ,the thread no must start with 1 for the next batch. But instead of that its creating 20 threads.please help. my code is as follows:

#!/usr/bin/perl -w
use strict;
use warnings;
use threads;
use threads::shared;

my $INPUT_DIR="/home/Documents/myscript/IMPORTLDIF/";
opendir(DIR, $INPUT_DIR) ;
my @files = grep { /^InputFile/ } readdir DIR;
my $count = @files;
#print "Total Files: $count \n";
my @threads;
my $noofthread = 5;
my $nooffiles = $count;
my $noofbatch = $nooffiles / $noofthread;
#print "No of batch: $noofbatch \n";

my $fileIndex = 0;
my $batch = 1;
while ($fileIndex < $nooffiles) {
    print "Batch: $batch \n";
    for (my $i=0; $i < $noofthread && $fileIndex < $nooffiles ; $i++) {

        my $t = threads->new(\&doOperation, $files[$fileIndex], $i)->join;
        push(@threads, $t);
        $fileIndex++;
        print "FileIndex: $fileIndex \n";
    }
    $batch++;
}

sub doOperation () {
    my $ithread = threads->tid() ;
    print "Thread Index : [id=$ithread]\n" ;
    foreach my $item (@_){
        my $filename = $item;
        print "Filename name: $filename \n";
    }

使用线程队列编辑程序:

Edited program using thread queue:

    #!/usr/bin/perl -w 
    # This is compiled with threading support

    use strict;
    use warnings;

    use threads;
    use Thread::Queue;

    my $q = Thread::Queue->new(); # A new empty queue

    # Worker thread
    my $INPUT_DIR="/home/Documents/myscript/IMPORTLDIF/";
    opendir(DIR, $INPUT_DIR) or die "Cannot opendir: $!";

    my @thrs = threads->create(\&doOperation ) for 1..5;#for 5 threads
    #my @files = `ls -1 /home/Documents/myscript/IMPORTLDIF/`;
    my @files = grep { /^Input/ } readdir DIR or die "File not present present. \n";
    chomp(@files);

    #add files to queue
    foreach my $f (@files){
    # Send work to the thread
    $q->enqueue($f);
    print "Pending items: " + $q->pending()."\n";
    }

    $q->enqueue('_DONE_') for @thrs;
    $_->join() for @thrs;



    sub doOperation () {
    my $ithread = threads->tid() ;
    while (my $filename = $q->dequeue()) {
     # Do work on $item
    return 1 if $filename eq '_DONE_';
    print "[id=$ithread]\t$filename\n";
   }
    return 1;
    }

推荐答案

您正在生成一个线程,然后等待它完成之后再生成下一个线程,每个线程都处理一个文件.这就是为什么您看到的线程与文件一样多的原因.

You are spawning a thread and then waiting for it to complete before spawning the next, each thread handling one file. That is why you see as many threads as you have files.

my $t = threads->new(\&doOperation, $files[$fileIndex], $i)->join;
                                                             ^^^^--- This will block

相反,请尝试以下操作:

Instead try something like this:

....

# split the workload into N batches
#
while (my @batch = splice(@files, 0, $batch_size)) {
  push @threads, threads->new(\&doOperation, @batch);
}

# now wait for all workers to finish
#
for my $thr (@threads) {
  $thr->join;
}

顺便说一句, Thread :: Queue

As an aside, Thread::Queue and Thread-Pool might imply better designs for the work you want to do.

这篇关于Perl多线程程序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆