2010-08-12 44 views
1

我有一個perl對象,裏面有幾個函數。每個功能在主程序中調用一次。我想並行運行一些功能來節省時間。由於某些函數依賴於之前函數的結果,因此我無法將它們全部運行在一起。perl中的線程同步/調度

我認爲是這樣的:

  1. 對於每個功能不斷被初始化爲假,並通過當它結束功能設置爲true的標誌(例如func1的最後一行是$is_func1_done = 1) 。
  2. 使用一個循環啓動每個函數,該循環等待直到它所依賴的函數的所有標誌都爲真。例如:如果func1取決於func2func3則:

    sub func1 { 
        while (!($is_func2_done && $is_func3_done)) { 
        # do nothing 
        } 
        # do work 
    } 
    

然後我就可以立即開始對每個功能的線程,但每個功能的實際工作將開始只有當它準備。這有意義嗎?我在旗幟上需要任何鎖嗎?正在使用這樣的while循環常見? - 這個名詞忙着等待......也許我的大部分CPU時間將花費在這些while上?有沒有更標準的解決方案呢?

+0

非常,非常密切相關的討論http://stackoverflow.com/questions/3448167/basic-thread-hanlding-in-perl – pilcrow 2010-08-12 17:48:41

+0

@ pilcrow謝謝,我會試試看! – user418673 2010-08-12 17:57:12

回答

2

您應該使用$thr->join等待線程完成。

例如:

#!/usr/bin/perl 

use strict; use warnings; 
use threads; 

my @threads = map threads->create($_), qw(func1 func2); 
$_->join for @threads; 

my $thr3 = threads->create('func3'); 
$thr3->join; 

sub func1 { 
    for (1 .. 5) { 
     print "func1\n"; 
     sleep 1 + rand 3; 
    } 
    return; 
} 

sub func2 { 
    for (1 .. 5) { 
     print "func2\n"; 
     sleep 1 + rand 2; 
    } 
    return; 
} 

sub func3 { 
    print "Time to do some work\n"; 
} 

我不知道這是否是共同使用這種while循環:我不會。

+0

到目前爲止,我知道...但是「調度」與這樣的while循環是一個聰明的舉動? – user418673 2010-08-12 17:42:51

2

這是否有意義?

是 - 每個任務都知道它的先決條件,並在執行之前等待它們滿足。這是許多有效的設計之一,儘管隨着任務數量的增長以及它們之間的相互依賴關係變得更加複雜,您可能會發現難以擴展。

我在標誌上需要任何鎖嗎?

是的。這些標誌必須是shared,以便一個線程可以操作它們,另一個線程可以看到它,並且共享變量需要是lock()以便安全使用。

正在使用while while循環常用嗎? - 期待繁忙的等待想到

可悲的是,但不要這樣做,請。在Perl共享變量可以作爲條件變量通過這些線程可以發送通知給彼此:

sub func1 { 
    { 
     lock(%shared_state); 
     until ($shared_state{ "func2 done" } and $shared_state{ "func3 done" }) { 
      cond_wait(%shared_state); 
     } 
    } 
    # do work -- note that %shared_state is unlocked 

    # now tell others that we're done 
    lock(%shared_state); 
    $shared_state{ "func1 done" } = 1; 
    cond_broadcast(%shared_state); 
    # %shared_state will be unlocked, and broadcast delivered when we leave this scope 
} 

當你cond_wait,共享變量是解鎖,你的線程處於睡眠狀態。無需繁忙循環。

有沒有更標準的解決方案呢?

$thr->join,作爲Sinan suggests,是等待特定線程完成運行的一種簡單且自然的方式。 Thread::Semaphore可以提供類似但更復雜的功能(並且可以幫助將其初始化爲小於零的值)。一個共同的需要「等待這5個線程完成某件事」可以通過Thread::Barrier來實現。 TMTOWTDI。

+0

您使用通知的解決方案看起來很酷! – user418673 2010-08-12 18:19:10