2010-06-22 20 views
9

以下不會出現在併發線程運行如我所料,而是每個處理塊,直到它完成:如何在perl中運行併發線程?

my @arr = (1,2,3,4); 
foreach (@arr) { 
    threads->new(\&doSomething, $_)->join; 
} 

sub doSomething { 
    my $thread = shift; 
    print "thread $thread\n"; 
    sleep(5); 
} 

換句話說,這似乎是在執行相同非螺紋版本會:

my @arr = (1,2,3,4); 
foreach (@arr) { 
    doSomething($_); 
} 

我正在運行的activeperl v5.10.1 mswin32 86多線程

如何我運行得併發線程?

回答

12

請參閱perldoc threads

問題是在線程上調用join()等待它完成。你想產生線程,然後加入,不作爲一個操作產卵/聯合。

進一步看perldoc threads說:

threads->列表()

threads->列表(線程::全部)

threads->列表(線程運行:: )

threads->列表(線程::加入)

沒有參數(或使用線程::全部) 並在列表上下文中返回所有未連接的,未分離的線程對象的列表 。在標量上下文中, 返回相同的計數。

有了一個真正的參數(使用線程運行::), 返回被 仍在運行的所有非固定, 非分離線程對象的列表。

如果使用false參數(使用threads :: joinable),則返回所有未連接的,未分離的已完成運行的線程對象(即,其中 - > join()不會阻止)的列表。

您可以使用此循環和列表的線程,在接合時有可能,直到所有線程完成(你可能會希望有一個上限的等待時間,你會殺了他們,並中止)

+0

我已經嘗試過 - 只是一次產卵,然後遍歷線程並加入,但只要第一次連接被調用,它就會阻塞。這幾乎就像我需要屈服,直到每個線程完成,然後加入,但我不太確定如何做到這一點。 – user210757 2010-06-22 16:37:50

+4

確切地說。 'join'是一個阻塞操作。但是當主進程等待'join'返回時,已經產生的線程將繼續運行。在這種情況下,如果您產生了所有線程,然後加入,您會期望第一次加入呼叫需要約5秒鐘,而其他所有加入呼叫都很短。 – mob 2010-06-22 16:44:27

+0

標記爲答案。列表(),結合is_joinable是我需要 - 謝謝 – user210757 2010-06-22 17:39:22

3

join(不僅在Perl中)導致調用線程等待另一個線程完成。因此,你的例子產生了線程,等待它完成,然後產生另一個線程,所以你會得到沒有任何線程產生的印象。

+0

我將如何實現這一點呢? – user210757 2010-06-22 16:43:33

12

,你必須參加他們事後,而不是在建立它們:

my @arr = (1,2,3,4); 
my @threads; 
foreach (@arr) { 
    push @threads, threads->new(\&doSomething, $_); 
} 
foreach (@threads) { 
    $_->join(); 
} 
1

你必須調用join產卵的所有主題:

perl -mthreads -le'$_->join for map threads->new(sub{print"Thread $_";sleep(2)}),1..4' 
3

如果你不關心的從線程生成的輸出,可以在線程上使用 - > detach()。

my @arr =(1,2,3,4); my @threads; foreach(@arr){
my $ t = threads-> new(\ & doSomething,$ _); $ t-> detach(); }

線程完成後,它將被回收,並且不需要在其上調用join()。

這個模型是很好的創建工蜂,你不需要向你報告。

0
my @arr = (1,2,3,4); 
my @threads; 
foreach (@arr) { 
    push @threads, threads->new(\&doSomething, $_); 
} 
foreach (@threads) { 
    $_->join(); 
} 

上述代碼工作在一個小規模。但是如果你有幾十個或更多的線程,你的操作系統就會開始停頓。

相關問題