在Perl中,子线程如何向主线程发出信号,表明不应再创建线程?

时间:2014-05-22 09:05:38

标签: multithreading perl

我在从perl中的线程返回一个值时遇到了一些问题。

我正在使用的代码是:

use threads;
foreach $num(1 .. 100)
{
    push(@threads, threads->create (\&readnum, $num));
    sleep(1) while(scalar threads->list(threads::running) >= 10);
}
$_->join foreach @threads;
sub readnum {
    # some code here
}

所以我想从readnum返回一个值,即:

use threads;
foreach $num(1 .. 100)
{
    if($ok)
    {
        push(@threads, threads->create (\&readnum, $num));
        sleep(1) while(scalar threads->list(threads::running) >= 10);
    }
}
$_->join foreach @threads;
sub readnum {
    # some code here
    return $ok ? "1" : "0";
}

所以我想检查$ok的值,如果它是真的,它将创建一个新线程。

编辑: 我想要的是检查$ ok值,如果它是真的它将创建一个新线程并保持进度,否则它停止。没有线程的相同想法:

foreach $num(1 .. 100)
{
$ok = readnum($num);
print "runing\n";
die "stoped\n" if $ok eq 1;
}
sub readnum {
    # some code here
$_[0]/5 eq 2 ? return 1 : return 0;
    }

但是使用线程我无法将返回的值放在$ ok中。 希望现在很清楚。感谢

1 个答案:

答案 0 :(得分:0)

您尝试做的不是从线程返回值,而是让一个线程能够向主线程发出信号,表明不应再创建线程。您可以通过创建shared global来实现。在下面的示例中,随机线程有1/20的机会决定应该停止处理。

可能有其他更好的方法来处理您的特定问题(例如,每个线程将结果推送到共享数组,主线程检查有多少结果等),但这似乎符合您的情况。

#!/usr/bin/env perl

use strict;
use warnings;

use threads;
use threads::shared;

my $KEEP_GOING :shared;
$KEEP_GOING = 1;

my @threads;
THREAD:
for my $num (1 .. 100) {
    sleep 1 while threads->list(threads::running) >= 10;
    {
        lock $KEEP_GOING;
        if($KEEP_GOING) {
            push @threads, threads->create(\&readnum, $num);
        }
        else {
            print "Won't create thread for $num .. Goodbye!\n";
            last THREAD;
        }
    }
}

$_->join for @threads;

sub readnum {
    my $num = shift;
    printf "Thread id: %d\tnum = %d\n", threads->tid, $num;
    sleep 1 + rand(3);
    {
        lock $KEEP_GOING;
        if (0.05 > rand) {
            $KEEP_GOING = 0;
        }
    }
}

输出:

Thread id: 1    num = 1
Thread id: 2    num = 2
Thread id: 3    num = 3
Thread id: 4    num = 4
Thread id: 5    num = 5
Thread id: 6    num = 6
Thread id: 7    num = 7
Thread id: 8    num = 8
Thread id: 9    num = 9
Thread id: 10   num = 10
Won't create thread for 11 .. Goodbye!