2012-12-04 2 views
2

이 프로그램에서는 포크를 만든 다음 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"; 
} 

나는 포크와 스레드를 죽일 수 있기를 원하지만 알아낼 수는 없다. 어떤 제안?

고마워요

+1

모든 스레드가 동일한 프로세스에 속하는; '$ pid'를 죽이면 모든 스레드가 암시 적으로 종료됩니다. 어떤 종류의 "정상적인 종료"를 시도하고 있습니까? – creaktive

+0

@creaktive 글쎄, $ pid를 죽이면 쓰레드가 계속 실행 중이다. "Perl은 활성 스레드에서 빠져 나갔다 : 10 개가 실행 중이고 결합되지 않았다" –

답변

5

Perl은 프로세스와 스레드의 두 가지 동시성 모델을 제공합니다. 좋은 이유없이이 두 가지를 꼭 섞어서는 안되지만 스레드는 모델 프로세스를 아주 가깝게 처리하므로 거의 처리 할 수 ​​있습니다. 특히 스레드에 신호를 보낼 수 있습니다. $thr->kill(SIGNAL) : 스레드가 kill 방법으로 시그널링 될 수있는 반면, kill SIGNAL => $pid :

프로세스는 kill 함수로 시그널링 될 수있다. 이 메소드는 스레드 객체를 리턴합니다. 신호 처리기를 %SIG 해시로 설정하면 신호를 가로 챌 수 있습니다.

이것은 청소 않는 모든 프로세스 TERM 신호 처리기 TERM

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

모든 스레드 TERM 신호 처리기는 단순히 스레드를 종료하거나 같은 모든 자식 스레드이야 것을 의미 :이

threads->exit; # exit the current thread 
+0

kill (TERM)을 죽이기 위해 스레드 목록을 통해 루프가 있어야한다는 것을 거의 이해하고있다. $ thr-> kill (SIGNAL) 각각? –

+1

@OwenGarland 예,하지만 신호로 barewords를 사용하면 작동하지 않습니다. 루프에 대한 첫 번째 코드 예제를 참조하십시오. '$ _ '는 각 스레드 객체를 연속적으로 나타냅니다. 자세한 정보는 ['threads' 문서] (http://search.cpan.org/~jdhedden/threads-1.86/lib/threads.pm#THREAD_SIGNALLING)의'kill' 메쏘드를보십시오. 자세한 정보는 ['% SIG'docs] (http://perldoc.perl.org/perlvar.html#%25SIG), ['perldoc -f kill'] (http://perldoc.perl.org /functions/kill.html) 및 ['perlipc'] (http://perldoc.perl.org/perlipc.html#Signals)를 참조하십시오. – amon

+0

고마워요! 알았어 :) –

1

실제로 실현하려는 방법에 따라 Perl에서 thread을 죽이는 몇 가지 다른 방법이 있습니다.

이의 예로서 다음 코드를 보자 :

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()을 사용하면 $ 스레드이 주밍 될 때까지 기다리는 것이 좋습니다.

$ queue-> end()을 선언하지 않으면 스레드가 주 스레드에 참가하지 않고 대기열의 새 요소를 보류합니다.

이제 스레드를 죽이려면 두 가지 옵션이 있습니다. 즉, 스레드를 죽이지 만 먼저 수행중인 작업을 완료하도록하거나 단순히 스레드를 즉시 (잔인하게) 종료합니다. Perl에서는 모두 Thread Signalling을 통해 이루어집니다.

첫 번째 경우 (즉, 스레드에게 작업 완료를 알리고 공유 대기열 처리를 중단하려는 경우) $ 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"; 
} 

한편, 후자의 경우우리가) 바로 스레드를 죽이고 싶은 경우에, 우리는 $ 스레드 -> 죽 ('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-> 종료() 전화를 걸거나 단순히 return 사용할 필요가 :

sub do { 
    ... 
    threads->exit(); # kill the thread... 
    ... 
} 
관련 문제