2011-08-24 23 views
3

我是相當新的Perl的線程,所以我想知道正確的方式在Perl做到這一點:的Perl:終止線程,並得到最好的結果,到目前爲止

for $input (@inputs) { 
    push @threads, start_thread($input); 
} 

for $thread (@threads) { 
    wait_for_external_event(); 
    $thread->kick_thread_out_of_loop(); 
    $result = $thread->result(); 
    print $result; 
} 

sub my_thread { 
    my $input = shift; 
    while(1) { 
    my $result = compute($best_result_so_far,$input); 
    if($result > $best_result_so_far) { 
     $best_result_so_far = $result; 
    } 
    } 
    # The thread got kicked out of the loop 
    return $best_result_so_far; 
    do_some_cleanup_that_is_slow(); 
    exit thread; 
} 

我有感覺的方式來踢從計算循環中退出的線程是通過使用信號並在線程中有一個信號處理程序。但也許有更漂亮的方法來做到這一點。我需要一些關於如何實現這一點的幫助,特別是如何返回$ best_result_so_far並在返回之後執行緩慢清理。在得到結果之前,我不必等待清理是非常重要的。

---編輯---

我已經看了看教程,我無法找到正在運行的線程通信的例子(「加入」不僅垂死線程)。我能得到的結果回來從正在運行的線程,類似於:

for $input (@inputs) { 
    push @threads, start_thread($input); 
} 

for $thread (@threads) { 
    wait_for_external_event(); 
    $result = $thread->result(); 
    $thread->kill("KILL"); 
    print $result; 
} 

package ThreadObj; 

sub my_thread { 
    my $self = shift; 
    my $input = shift; 

    local $SIG{KILL} = sub { 
    do_slow_cleanup(); 
    threads->exit(); 
    }; 

    while(1) { 
    my $result = compute($best_result_so_far,$input); 
    if($result > $self->{'best_result_so_far'}) { 
     $self->{'best_result_so_far'} = $result; 
    } 
    } 
} 

sub result { 
    my $self = shift; 
    wait until (defined $self->{'best_result_so_far'}); 
    return $self->{'best_result_so_far'}; 
} 

回答

1

據我所知,這是不可能的從一個線程返回結果,並推遲線程清理以後。

如果$best_result_so_far是所有線程通用(督察只有一個最好的結果),那麼threads::shared和信號燈可以幫助(雖然在性能上的開銷)。看到perldoc perlthrtut一些很好的初學者的例子。

感覺這個問題更適合基於事件的編程範例。可能Coro::AnyEvent是適合這份工作的正確工具?

+0

聽起來像coroutines(按照Coro)的確可以比普通線程工作得更好。 – bart

+0

沒有最好的結果。結果取決於輸入,每個線程得到不同的輸入。 –

1

我會使用一個通用的數據結構或兩個通信,其中每個線程使用自己的唯一ID訪問共享哈希中的條目來存儲其當前結果。用同樣的方法使用第二個哈希值作爲標誌,告訴線程它是放棄的時間 - 或者是所有線程必須同時退出的單個常用標量。只要沒有設置標誌,就會循環,而不是無限循環。