如何在Perl中唤醒一个线程

时间:2011-05-14 10:36:53

标签: multithreading perl

有没有办法在Perl中使用其线程ID唤醒睡眠线程?提前致谢

以下是我尝试使用暂停和恢复的内容

use warnings;
use strict;
use threads;
use threads::shared;
use Thread::Suspend;  

my $val:shared = 0;
my $count = 0; 
while ( $count < 4 )
{
    my $thr = threads->create( \&worker );
    $count++;
}

use Tk;
my $mw = MainWindow->new();
$mw->protocol('WM_DELETE_WINDOW' => sub { &clean_exit }); 
my $thr;
my $button;
$button = $mw->Button(
        -text => 'Invoke thread',
        -command => sub{
            $val += 1;
            if( $val > 4)
            {
                $val = 1;
            }   
            foreach $thr (threads->list()) 
            {
                if( $thr->tid() == $val )
                {
                    $thr->resume();
                    goto OUTSIDE;
                }
            }
            OUTSIDE:                                                
        })->pack();

MainLoop;

sub clean_exit
{
    my @running_threads = threads->list;
    if (scalar(@running_threads) < 1)
    {
        print "\nFinished\n";
        exit;
    }
    else
    {
        foreach my $thr (threads->list()) 
        {
            $thr->kill('KILL')->detach();
        }
        exit;
    }
}

sub worker
{
    $SIG{'KILL'} = sub { threads->exit(); };
    threads->suspend();
    print threads->tid()."\n";  
}

我想要做的是当用户点击Invoke按钮时,它应该根据$ val恢复线程。但它不是那样工作的。 ID4的第一个线程也会在4次点击后恢复,而不是1.请帮助调试代码。附:我是Perl的新手

1 个答案:

答案 0 :(得分:4)

#!/usr/bin/perl
use warnings;
use strict;
use threads;
use threads::shared;
use Thread::Suspend;  

my $val:shared = 0;
my $count = 0; 
my @thr;

while ( $count < 4 )
{
    $thr[$count] = threads->create( \&worker, $count );
    $count++;
}

use Tk;
my $mw = MainWindow->new();
$mw->protocol('WM_DELETE_WINDOW' => sub { &clean_exit }); 
my $button;
$button = $mw->Button(
        -text => 'Invoke thread',
        -command => sub{
            foreach my $th (@thr)
            {
                    print "Resuming...\n";
                    $th->resume();
            }
        })->pack();

MainLoop;

sub clean_exit
{
    my @running_threads = threads->list;
    if (scalar(@running_threads) < 1)
    {
        print "\nFinished\n";
        exit;
    }
    else
    {
        foreach my $th (@thr) 
        {
            $th->kill('KILL')->detach();
        }
        exit;
    }
}

sub worker
{
    my($id)=@_;
    $SIG{'KILL'} = sub { print "Die...\n";threads->exit(); };
    threads->self->suspend();
    print "Worker:Resuming....\n";
    while(1){
        print threads->tid()." $id\n";  
        sleep(1);
    }
}