2012-09-11 117 views
1

我有一個簡單的Perl腳本,我有一個BIG循環,在這裏我調用了多少次或多少次的函數my_fun()。我想創建將處理它的線程池 - 在同一時間最多5個線程將​​在循環中調用此方法。如何在Perl中創建線程?

對我來說,使用速度最快的圖書館真的很重要 - 看到例子會很高興。

我的代碼如下所示:

for (my $i = 0; $i < 1000000 ; $i++) { 
     my_fun(); 
} 

預先感謝您

+4

要你真的需要** **線程(如,共享內存,併發控制),或僅僅是獨立並行執行?如果是後者,考慮Parallel :: ForkManager - POD有一個很容易的方法來做5次分叉的例子。 – DVK

+0

@DVK我沒有看到您的評論。不想竊取你的想法,對不起。 – simbabque

+1

@simbabque - 沒有任何問題。 (1)我懶得查看細節併發帖; (2)關於SO的內容是CC,我不擁有它:); (3)不像我從來沒有借過評論的想法來回答,雖然像你,我總是明確地告訴評論者。無論如何,+1代表一個很好的示例代碼 – DVK

回答

11

看一看Parallel::ForkManager。它使用的是fork,而不是線程,但它應該能夠非常簡單地完成工作。

例如,從文檔提起並稍微改變:

use Parallel::ForkManager; 

my $pm = Parallel::ForkManager->new(5); # number of parallel processes 

for my $i (0 .. 999999) { 
    # Forks and returns the pid for the child: 
    my $pid = $pm->start and next; 

    #... do some work with $data in the child process ... 
    my_fun(); 

    $pm->finish; # Terminates the child process 
} 

$pm->wait_all_children; 
+0

Windows的任何解決方案是這樣的? – javaGirl

+0

@javaGirl它應該在Windows上工作。我只是在Windows上測試它,它適用於我。 – simbabque

0

看看在threads文檔。

+0

是的,當然我已經讀過了,但是我需要最快的方式,所以爲什麼我要求 – javaGirl

+2

@javaGirl [Benchmark](http://search.cpan.org/perldoc?Benchmark)呢? – TLP

+1

@javaGirl然後你可能會這麼說... – JRFerguson

3

我們不能給你最快的方法,因爲這依賴於工作,而你沒有告訴我們的工作是什麼。

但你確實詢問過線程,所以我會給你一個線程應用程序的基礎。這是一個工人模型。它強大,可維護和可擴展。

use threads; 
use Thread::Queue qw(); # Version 3.01+ required 

my $NUM_WORKERS = 5; 

sub worker { 
    my ($job) = @_; 
    ... 
} 

my $q = Thread::Queue->new(); 
my @workers; 
for (1..$NUM_WORKERS) { 
    push @workers, async { 
     while (defined(my $job = $q->dequeue())) { 
     worker($job); 
     } 
    }; 
} 

$q->enqueue($_) for @jobs;  # Send work 
$q->end();      # Tell workers they're done. 
$_->join() for @workers;   # Wait for the workers to finish. 

這是一個基本流程(單向),但很容易通過添加一個響應隊列來實現雙向。

這使用實際的線程,但您可以切換到use threads;use forks;使用進程。

Parallel::ForkManager也可以用來提供工作者模型,但它不斷地創建新的過程而不是重新使用它們。不過,這確實可以輕鬆應對兒童死亡。

編號:Thread::Queue(或Thread::Queue::Any