2009-09-04 12 views
5

Chciałbym zadzwonić do innych skryptów Perla, aby wykonać test rywalizacji z głównym skryptem Perla.Jak mogę użyć wywołania systemowego Perla do odrodzenia niezależnych wątków?

Coś jak to działa obecnie:

system("perl 1.pl"); 
system("perl 2.pl"); 
exit; 

Jednak chciałbym skopać ci się jako niezależne wątki uruchomione w tym samym czasie.

Próbowałem, na podstawie moich wyszukiwań Google robi coś takiego:

system(1, "perl 1.pl"); 
system(1, "perl 2.pl"); 
exit; 

to nie zadziała. Główny skrypt istnieje od razu, co jest w porządku, ale podstawowe wątki, które chcę odrodzić, nie zostaną odrzucone. Zastanawiałem się, czy jest coś innego, co muszę zrobić, czy też ktoś inny zrobił coś takiego.

Dzięki za pomoc z góry.

+1

Chcesz wątków lub procesów? Funkcja 'system()' Perla tworzy pod-proces (i czeka na jego zakończenie przed wykonaniem następnej instrukcji Perl.Te wywołania do 'system (1, ...)' nie wyglądają jak cokolwiek znaczącego (fork(), następnie execve() jakiś rzekomy program o nazwie "1" z argumentem "perl ..."). Jeśli chcesz subprocesów, usuń znacznik "wątków" z tego pytania –

Odpowiedz

13
use threads; 
$thr1 = threads->create('msc', 'perl 1.pl'); 
$thr2 = threads->create('msc', 'perl 2.pl'); 

$thr1->join(); 
$thr2->join(); 

sub msc{ ## make system call 
    system(@_); 
} 

To spowoduje, że oba zostaną zakończone, zanim zostanie zakończony. Zgaduję, że tego właśnie chcesz od pierwotnego pytania, prawda? Jeśli nie, wyślij komentarz i edytuj swój post, aby lepiej go objaśnić, a spróbuję ponownie.

+3

Powinieneś naprawdę użyć '$^X' zamiast liczyć na 'perl' znajdujący się w PATH –

+0

Nie jest trudno odgadnąć z kontekstu, ale spojrzałem w górę $^X: w użyciu angielski to $ EXECUTABLE_NAME -" Nazwa użyta do wykonania bieżącej kopii Perl " –

3

Użyj polecenia widelca, aby to zrobić, lub wykonaj to ze skryptu powłoki. Skrypt powłoki (tylko Unix) będzie wyglądać następująco:

nohup perl 1.pl & 
nohup perl 2.pl & 
exit 

a perla polecenie będzie wyglądać następująco:

if (! fork()) 
{ 
    system("perl 1.pl"); 
} 
if (! fork()) 
{ 
    system("perl 2.pl"); 
} 

Są lepsze sposoby, aby to zrobić, czyli napisać twierdzenie w jednym skrypcie za pomocą perl, ale to zadziała. Upewnij się, że w swoim skrypcie macierzystym dodajesz funkcję SIG_CHLD z funkcją wait(). Więcej informacji na temat tego rodzaju obsługi zdarzeń można znaleźć tutaj. Podczas gdy system ("perl 1.pl &"); może działać (nie testowałem tego), myślę, że rozwidlanie i czekanie jest zbyt cennym zasobem, o którym nie wspomnę.

+1

Aby uzyskać więcej informacji: http://search.cpan.org/dist/perl/pod/perlipc.pod – Horus

+0

Zakłada to, że korzystasz z platformy obsługującej nohup ... – Kev

+0

Możesz równie dobrze widelec, jak i exec. –

2

Wystarczy popatrzeć na Parallel::ForkManager na CPAN - zapewnia schludniejszy interfejs do gwintowania, który powinien zrobić dokładnie to, czego szukasz, aby zrobić;)

4

Można fork off procesy pozwalające na wykonywanie komend dla ciebie. Jeśli to zrobisz, będziesz prawdopodobnie chcesz użyć exec zamiast system:

#!/usr/bin/perl 

use strict; 
use warnings; 

die "could not fork: $!" unless defined (my $first_pid = fork); 

#first child 
exec $^X, "1.pl" unless $first_pid; 

die "could not fork: $!" unless defined (my $second_pid = fork); 

#second child 
exec $^X, "2.pl" unless $second_pid; 

waitpid $first_pid, 0; #wait for first child to finish 
waitpid $second_pid, 0; #wait for second child to finish 

Zobacz także: $^X i waitpid

Powiązane problemy