3

このプログラムでは、フォークを作成し、そこからdomultithreadingを呼び出します。次に、いくつかのスレッドを作成します。

sub domultithreading {
    #Not my function
    my ($num) = @_;
    my @thrs;
    my $i = 0;
    my $connectionsperthread = 50;
    while ( $i < $num ) {
        $thrs[$i] = threads->create( \&doconnections, $connectionsperthread, 1 );
        $i += $connectionsperthread;
    }
    my @threadslist = threads->list();
    while ( $#threadslist > 0 ) {
        $failed = 0;
    }
}

sub kill {
    #how can I kill the threads made in domultithreading?
    kill 9, $pid;
    print "\nkilling $pid\n";
}

次に、フォークとそのスレッドを強制終了できるようにしたいのですが、理解できません。助言がありますか?

どうもありがとう

4

2 に答える 2

5

Perlは、プロセスとスレッドの2つの並行性モデルを提供します。正当な理由なしにこれら2つを必ずしも混合するべきではありませんが、スレッドはモデルプロセスを非常に厳密に実行するため、ほぼそのように扱うことができます。具体的には、スレッドにシグナルを送信できます。

プロセスはkill 関数kill SIGNAL => $pidで通知でき、スレッドはkill メソッド:で通知できます$thr->kill(SIGNAL)。このメソッドはスレッドオブジェクトを返します。%SIGハッシュにシグナルハンドラーを設定すると、シグナルがインターセプトされる可能性があります。

これは、すべてのプロセスTERMシグナルハンドラが次TERMのようなすべての子スレッドであることを意味します。

 $_->kill(9)->join() for threads->list;

そして、すべてのスレッドTERM信号ハンドラーは、単にスレッドを終了するか、クリーンアップを行います。

 threads->exit; # exit the current thread
于 2012-12-04T18:19:26.170 に答える
2

達成したいことに応じて、Perlでスレッドを強制終了する方法は実際にはいくつかあります。

次のコードを例として取り上げましょう。

use strict;
use warnings;
use threads;
use Thread::Queue;

# Create the shared queue (used by the threads):
my $queue = Thread::Queue->new();

sub main {    
    # Initialise the shared queue:
    $queue->enqueue("A", "B", "C", "D", "E", "F");
    print "Total number of items: " . $queue->pending() . "\n";
    $queue->end();  # signal that there is no more work to be sent...

    # Create 3 threads:  
    threads->create('do') for ( 0..2 );
    print "Number of current threads: " . threads->list() . "\n";

    foreach my $thread ( threads->list() ) {  # for each thread...
        $thread->join();  # wait the thread to finish all its work...

        print "Number of items in the queue: " . $queue->pending() . "\n" if defined $queue->pending();
        print "Number of current threads: " . threads->list() . "\n";
    }
}

sub do {
    # Retrieve the current thread ID:
    my $threadID = threads->self()->tid();

    # Setup the thread's kill signal handler:
    local $SIG{KILL} = sub { threads->exit() };

    while ( defined (my $item = $queue->dequeue()) ) {  # for each element in the queue...
        print "(Thread-" . $threadID . "): Do something with item '$item'...\n";
        sleep 1 + $threadID;
        print "(Thread-" . $threadID . "): Finished to use item '$item'...\n";
    }
}


main();

上記のコードは3つのスレッドを生成します。各スレッドは、キューが空になるまで共有キューの要素を取得して処理します。

この場合、これ以上要素がキューに追加されないことを宣言したため(つまり、$ queue-> end())、スレッドは、キューのすべての要素を処理した後、(メインに)参加します。実際、$ thread-> join()を使用して、 $threadが参加するのを待つようにメインに言っています。

$ queue-> end()の宣言を省略した場合、スレッドはメインに参加しませんが、キューの新しい要素に対して保留状態のままになります。

ここで、スレッドを強制終了する場合は、2つのオプションがあります。スレッドを強制終了するが、最初に実行していることを終了させるか、単に(残酷に)スレッドをすぐに強制終了します。Perlでは、両方ともスレッドシグナリングを介して実現されます。

最初のケース(つまり、スレッドに作業を終了し、その後、共有キューの処理を停止するように指示する場合)は、$ thread-> kill('KILL')-> join()を使用する必要があります。

foreach my $thread ( threads->list() ) {  # for each thread...
    $thread->kill('KILL')->join();  # wait the thread finish its work and kill it...

    print "Number of items in the queue: " . $queue->pending() . "\n" if defined $queue->pending();
    print "Number of current threads: " . threads->list() . "\n";
}

一方、後者の場合(つまり、スレッドをすぐに強制終了する場合)は、 $ thread-> kill('KILL')-> kill()を使用する必要があります。

foreach my $thread ( threads->list() ) {  # for each thread...
    $thread->kill('KILL')->kill();  # kill the thread immediately...

    print "Number of items in the queue: " . $queue->pending() . "\n" if defined $queue->pending();
    print "Number of current threads: " . threads->list() . "\n";
}

もちろん、スレッド自体を強制終了する場合は、 threads-> exit()を呼び出すか、単にreturn:を使用する必要があります。

sub do {
    ...
    threads->exit();  # kill the thread...
    ...
}
于 2014-12-29T14:41:08.670 に答える