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

セマフォが機能していないように見える理由は、子プロセス$semfork-ed になると独自のコピーを保持するためです。

ourキーワードはパッケージ$semスコープを指定します。変数がプロセス間で共有されるという意味ではありません。

おそらく最も簡単な修正方法は、明示的な fork の代わりにスレッドを使用して子プロセスを実行することです。

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 に答える