2014-09-19 67 views
1

我有運行多個線程,並推動他們到主題列表的模塊。我可以在Perl中重複使用連接的線程嗎?

例如:

#!/usr/bin/perl 

#test_module.pm 

package test_module; 

use strict; 
use warnings; 
use threads; 

sub main { 

    my $max_threads = 10; 
    my @threads  =(); 

    # create threads 
    while (scalar @threads < $max_threads) { 
     my $thread = threads->new(\&thread_sub); 
     push @threads, $thread; 
    } 

    # join threads 
    for my $thread (@threads) { 
     $thread->join(); 
    } 
} 

sub thread_sub { 
    my $id = threads->tid(); 
    print "I am in thread $id\n"; 
} 

1; 

的問題是,我多次從一個Perl腳本調用此模塊,而不是消除舊的線程和創建新的,該線程ID不斷遞增。我聽說如果你在Perl中沒有正確地擺脫舊線程,這會導致內存泄漏並減慢你的程序,這是真的嗎?來自我的舊線程的數據是否坐在內存佔用空間?

如果是的話這會成爲一個大問題,因爲我的劇本將是一個可能產生的線程數百或數千所有這些也只是佔用了他們這樣做即使正在使用的內存更大的計劃的一部分。我怎樣才能阻止這種情況發生?我的線程可以重用嗎?

這是一個示例腳本,它將調用模塊並顯示線程將如何繼續遞增,即使我加入了舊線程(我認爲「加入」是您在他們之後如何清理,我是否做錯了什麼?)這個腳本將被使用的方式我無法承受坐在那裏佔用空間的舊線程的內存。

例如:

#!/usr/bin/perl 

#testing.pl 

use strict; 
use warnings; 
use test_module; 

test_module::main(); 
test_module::main(); 
test_module::main(); 

system 'pause'; 

謝謝!

+0

你爲什麼要線程ID可以重複使用? – 2014-09-19 15:36:41

+1

我想我真正想知道的是,如果所有的線程內存都是真正在「加入」時發佈的。事實上,ID不斷增加使得它看起來像舊線程仍然以某種方式在內存中,即使它們已經「加入」了。 – tjwrona1992 2014-09-19 15:42:53

+4

線程ID遞增與進程ID遞增一樣多的紅色鯡魚。也不意味着疲憊正在發生。 – Sobrique 2014-09-19 15:42:58

回答

3

不要擔心遞增線程ID - 這並不意味着正在運行的線程的數量正在增加。一旦線程join已完成執行並被終止。

然而,不斷重生線程不理想或者 - 創建一個線程不是Perl中的一個特別輕操作。所以,如果你必須做這樣的事情,並特別側重於效率 - 看fork()代替。

我發現我傾向於使用「工作線程」的模式,利用Thread::Queue

my $processing_q = Thread::Queue -> new(); 

sub worker_thread { 
    while (my $item = $processing_q -> dequeue()) { 
     # do stuff to $item 
    } 
} 

for (1 .. $num_threads) { 
    my $thr = threads -> create (\&worker_thread); 
} 

$processing_q -> enqueue (@generic_list_of_things); 
$processing_q -> end; 

foreach my $thread (threads -> list()) { 
    $thread -> join(); 
} 

這將一批物品送入一個隊列,你的工作線程會處理他們一次一個 - 意味着你可以運行一個合理的號碼,而不必連續重生。

作爲替代 - 看看Parallel::ForkManager - fork風格的並行處理最初看起來可能違反直覺,但fork()是Unix系統上的本地系統調用,所以它往往會得到更好的優化。

+0

我基本上創建了自己的隊列,但是我會考慮這個模塊,因爲它可能會簡化一些事情。 – tjwrona1992 2014-09-19 15:46:15

+0

它有內置的鎖定語義,這使得它更加整潔。不一定更有效的頭腦,但明確的代碼有它自己的優點。特別是我喜歡'end()'選項 - 因爲那麼你的子循環中的'while循環將返回'undef'並退出。 – Sobrique 2014-09-19 15:48:19

相關問題