2012-02-22 22 views
6

Tôi đang viết một tập lệnh Perl (nói script.pl) gọi một tập lệnh khác newscript.pl. Tôi muốn nhận được PID của cả hai kịch bản chỉ trong script.pl. Tôi có thể lấy PID của script.pl bằng cách sử dụng mã sauLàm cách nào để lấy PID của quá trình sinh ra với chức năng hệ thống của Perl?

my $pid = Unix::PID->new(); 
my @p = $pid->get_pidof($pid->get_command($$), 1); 

Sau này tôi gọi system để thực hiện newscript.pl

system("perl newscript.pl"); 

Tôi muốn chụp các PID được tạo ra bởi newscript.pl này trong script.pl.

Trả lời

5

Đến thời điểm system trả về, quá trình sinh sản sẽ đã thoát, để lại pid của nó làm tham chiếu lịch sử thú vị — hữu ích cho phân tích nhật ký, ví dụ.

system LIST
system PROGRAM LIST

Liệu chính xác những điều tương tự như exec LIST, ngoại trừ một fork được thực hiện đầu tiên và quá trình cha mẹ chờ cho quá trình con để thoát & hellip;

Nếu bạn muốn PID của cả hai script.plnewscript.pl, fork và quản lý cuộc đời của mình cho mình. Với thông tin cụ thể hơn về sự cố bạn ’ giải quyết lại, chúng tôi có thể cung cấp cho bạn các đề xuất cụ thể hơn.


Để chặn trường hợp khác của một chương trình, một kỹ thuật phổ biến là sử dụng hệ điều hành ’ s cơ sở cho hợp tác xã khóa: lúc khởi động, nỗ lực để khóa một tập tin nhất định. Nếu thành công, chương trình của bạn biết nó chỉ là ’ s. Nếu không, một quy trình khác đã có khóa, vì vậy quy trình mới sẽ thoát. Xem ví dụ bên dưới.

#! /usr/bin/env perl 

use strict; 
use warnings; 

use Fcntl qw/ :flock /; 
use File::Basename; 
use POSIX qw/ strftime /; 

$0 = basename $0; 

my $LOCK = "$ENV{HOME}/.lock-$0"; 

sub logmsg { 
    my($msg) = @_; 
    my $t = strftime "%F %T", localtime time; 
    warn "$0: $t - $$ - $msg\n"; 
} 

sub take_lock { 
    open my $fh, ">", $LOCK or die "$0: open $LOCK: $!"; 

    unless (flock $fh, LOCK_EX | LOCK_NB) { 
    logmsg "failed to lock $LOCK; exiting."; 
    exit 1; 
    } 

    $fh; 
} 

my $token = take_lock; 
logmsg "processing..."; 
sleep 2 * 60; 
logmsg "done."; 

Lưu ý rằng bạn phải giữ filehandle trở về từ take_lock mở trong khi điều khiển là bên critical section của bạn. Mã trên xử lý nó như một mã thông báo mờ đục. Khi chương trình của bạn thoát ra, Perl sẽ đóng filehandle, tự động giải phóng khóa. Những gì bạn don ’ t muốn làm là gọi take_lock trong ngữ cảnh void vì điều đó sẽ hủy bỏ khóa của bạn.

+0

Tập lệnh script.pl của tôi thực hiện nhiệm vụ lên lịch các tập lệnh khác như newscript.pl và nhiều tập lệnh khác. Tôi không thể đi về lịch trình chúng trực tiếp trong cron và do đó nghĩ đến việc làm cho kịch bản này cha mẹ sẽ hành động như scheduler. Bây giờ, có thể có một trường hợp khi kịch bản được lập biểu lặp lại khi tôi lấy tên kịch bản từ databse MySql, tôi không muốn tập lệnh đang chạy để thực hiện lại và do đó tôi đã nghĩ rằng nếu tôi có thể nắm bắt các PID của các tập lệnh được lên lịch, Tôi có thể kiểm tra trên cơ sở của các Pids và tránh chạy đồng thời của cùng một kịch bản.Cảm ơn một Tôn đã giúp đỡ của bạn – Deepak

+0

Có cách nào khác để làm điều đó mà không cần sử dụng ngã ba? – Deepak

+0

Sử dụng 'flock()' nếu bạn cần độc quyền. 'sử dụng Fcntl qw (: đàn); flock ($ lockfd, LOCK_NB | LOCK_EX) hoặc chết "Cùng một kịch bản đã đi"; # ... 'Lưu ý rằng $ lockfd là một bộ mô tả tập tin và không phải tên tập tin (bạn phải mở nó trước khi bầy đàn). – Dallaylaen

9

Số quy trình của quy trình hiện tại là $$. Sử dụng open3 thay vì system để nhận được số quy trình của quy trình con.

Các vấn đề liên quan