2016-08-31 75 views
6

我有一個運行速度非常慢的函數。我需要在該程序的主要部分從該功能輸入。所以我想要做一些類似於UNIX命令yes的東西,它可以產生儘可能多的輸入,但只是比需要的多一點點。與yes不同,我不想從STDIN得到值,但我想要在Perl隊列中的值。Perl線程:如何製作製作人?

換句話說:這個問題不是關於選擇文件句柄,而是關於線程維護的隊列。

我想象中的元代碼將類似於此:

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

my @producers; 
my $no_of_threads = 10; 
for (1..$no_of_threads) { 
    push @producers, threads->create(\&producer); 
} 

for(<>) { 
    # This should block until there is a value to dequeue 
    # Maybe dequeue blocks by default - then this part is not a problem 
    my $val = $DataQueue->dequeue(); 
    do_something($_,$val); 
} 
# We are done: The producers are no longer needed 
kill @producers; 

sub producer { 
    while(1) { 
     # How do I wait until the queue length is smaller than number of threads? 
     wait_until(length of $DataQueue < $no_of_threads); 
     $DataQueue->enqueue(compute_slow_value()); 
    } 
} 

但有這樣做的更優雅的方式?我特別不確定如何以有效的方式完成wait_until部件。

+2

這種感覺極像是一個['XY problem'(http://meta.stackexchange.com/questions/66377/what-is-the -XY-問題)。爲什麼你想「加滿」隊列?隊列的全部內容是一批待完成的工作 - 你排隊等待,並讓它繼續運行。但是你總是可以使用'$ DataQueue - > pending'來查看那裏有多少物品。 – Sobrique

+0

問題是我想prespawn進程。將要傳遞的是處理的句柄。如果在同一個線程中完成,產卵永遠需要預熱。我完全沒有使用隊列,這就是爲什麼我問是否有一個更優雅的方式(例如沒有隊列)。 –

+1

好吧,也許這只是我,但我仍然沒有遵循你想要做的事情。沒有真正的理由,你不能只是開始一個線程來完成你的「預生成」過程,只是使用信號量或類似的方式來表示準備就緒。但是真的 - 一個充滿了東西的隊列,等待'產卵'完成啓動,就是......只要準備就緒就要等待。 – Sobrique

回答

0

像這樣的東西可能會工作:

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

my @producers; 
my $no_of_threads = 10; 
for (1..$no_of_threads) { 
    push @producers, threads->create(\&producer); 
} 
$DataQueue->limit = 2 * $no_of_threads; 

for(<>) { 
    # This blocks until $DataQueue->pending > 0 
    my $val = $DataQueue->dequeue(); 
    do_something($_,$val); 
} 
# We are done: The producers are no longer needed 
kill @producers; 

sub producer { 
    while(1) { 
     # enqueue will block until $DataQueue->pending < $DataQueue->limit 
     $DataQueue->enqueue(compute_slow_value()); 
    } 
}