0

这是我的代码的一部分,它并行编译了一些项目:

#main:#
our $sem = Thread::Semaphore->new();

for ($i = 0; $i < $cores_num-1; $i++)
{
    # Generating process
    local $curr_pid = fork ();
    # Child
    if ($curr_pid == 0)
    { 
        compiling_process($i,*REPORT);
        exit(0);
    }
    # Parent
    elsif (abs($curr_pid) > 10)
    {
        sleep (1);
        $running_processes++;   
    }
    # Error
    else
    {
        print "Error while forking!! \n";
        exit (0);
    }
}

# parent process:
compiling_process($i,*REPORT);
# Wait:
while ($running_processes > 0)
{
    $kid = 0;
    $kid = waitpid(-1,WNOHANG);
    if (abs($kid) > 10)
    {
        $running_processes--;
    }
    sleep (1);
}




sub compiling_process{
local $id = $_[0];
*REPORT = $_[1];
# Run until all targets are built:

while (1)   
{
$sem->down();   
##critical section
$sem->up();
}

}

此代码用于并行编译。在运行此代码时 - 有时我会同时在关键部分内看到 2 个内核!(代码运行良好,所有项目都在构建中,但我必须解决这个问题..它会浪费时间 + 打印错误)我有点绝望,因为我不知道我做错了什么。在函数中使用信号量是错误的吗?(“子编译过程”)

任何帮助,将不胜感激!非常感谢。

4

1 回答 1

1

信号量似乎不起作用的原因是因为子进程$sem一旦被fork-ed 就会维护它们自己的副本。

our关键字给出包$sem范围;这并不意味着变量是跨进程共享的。

可能最简单的解决方法是使用线程而不是显式分叉来运行子进程:

use threads;
use Thread::Semaphore;

my $sem = Thread::Semaphore->new;

my @threads;

for my $i ( 0 .. $num_cores-1 ) {

    my $thr = threads->new( \&compiling_process, $i, *REPORT ); # Launch
    push @threads, $thr;
}

$_->join for @threads;                                          # Wait

有关perldoc perlthrtut更多详细信息和示例,请参阅。

于 2012-08-26T14:31:50.130 回答