perl中的线程同步/调度

时间:2010-08-12 17:04:13

标签: multithreading perl synchronization scheduling

我有一个带有一些函数的perl对象。每个函数都从主程序调用一次。我想并行运行一些函数以节省时间。我无法将所有这些功能一起运行,因为某些功能取决于先前功能的结果。

我想到了这样的事情:

  1. 对于每个函数,保留一个初始化为false的标志,并在函数结束时由函数设置为true(例如func1中的最后一行将为$is_func1_done = 1)。
  2. 使用循环启动每个函数,该循环等待它所依赖的函数的所有标志都为真。例如:如果func1取决于func2func3,那么:

     sub func1 {
      while (!($is_func2_done && $is_func3_done)) {
       # do nothing
      } 
      # do work
     }
    
  3. 然后我可以立即为每个函数启动一个线程,但每个函数的实际工作只有在它准备就绪时才会启动。这有意义吗?旗帜上是否需要锁定?使用这种while循环常见吗? - 想到忙碌的等待一词......也许我的大部分CPU时间将花在这些while上?对此有更标准的解决方案吗?

2 个答案:

答案 0 :(得分: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循环是否常见:我不会。

答案 1 :(得分:2)

  

这有意义吗?

是 - 每个任务都知道它的前提条件,并等待它们在执行前得到满足。它是众多有效设计中的一种,但随着任务数量的增加和相互依赖性变得更加复杂,您可能会发现难以扩展。

  

旗帜上是否需要锁定?

是。标志需要为shared,以便一个线程可以操作它们而另一个线程可以看到它,共享变量需要lock()才能安全使用。

  

使用这种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->joinSinan suggests,是等待特定线程完成运行的简单而自然的方法。 Thread::Semaphore可以提供类似但更复杂的功能(并且有用的是,可以初始化为小于零的值)。使用Thread::Barrier可以实现“等待这5个线程完成某些事情”的常见需求。 TMTOWTDI。