Perl - Quản lý quy trình
Bạn có thể sử dụng Perl theo nhiều cách khác nhau để tạo các quy trình mới theo yêu cầu của bạn. Hướng dẫn này sẽ liệt kê một vài phương pháp quan trọng và được sử dụng thường xuyên nhất để tạo và quản lý các quy trình Perl.
Bạn có thể sử dụng các biến đặc biệt $$ hoặc là $PROCESS_ID để lấy ID quy trình hiện tại.
Mọi quy trình được tạo bằng bất kỳ phương pháp nào đã đề cập, đều duy trì môi trường ảo của riêng nó với %ENV Biến đổi.
Các exit() hàm luôn thoát khỏi tiến trình con thực thi chức năng này và toàn bộ quá trình chính sẽ không thoát trừ khi tất cả các tiến trình con đang chạy đã thoát.
Tất cả các chốt điều khiển đang mở đều bị trùng lặp () - ed trong các tiến trình con, do đó, việc đóng bất kỳ chốt điều khiển nào trong một quy trình không ảnh hưởng đến các quy trình khác.
Toán tử Backstick
Cách đơn giản nhất này để thực hiện bất kỳ lệnh Unix nào là sử dụng toán tử thanh ngược. Bạn chỉ cần đặt lệnh của mình bên trong toán tử cần gạt ngược, điều này sẽ dẫn đến việc thực thi lệnh và trả về kết quả của nó có thể được lưu trữ như sau:
#!/usr/bin/perl
@files = `ls -l`;
foreach $file (@files) {
print $file;
}
1;
Khi đoạn mã trên được thực thi, nó sẽ liệt kê tất cả các tệp và thư mục có sẵn trong thư mục hiện tại -
drwxr-xr-x 3 root root 4096 Sep 14 06:46 9-14
drwxr-xr-x 4 root root 4096 Sep 13 07:54 android
-rw-r--r-- 1 root root 574 Sep 17 15:16 index.htm
drwxr-xr-x 3 544 401 4096 Jul 6 16:49 MIME-Lite-3.01
-rw-r--r-- 1 root root 71 Sep 17 15:16 test.pl
drwx------ 2 root root 4096 Sep 17 15:11 vAtrJdy
Hệ thống () Chức năng
Bạn cũng có thể dùng system()hàm để thực thi bất kỳ lệnh Unix nào mà đầu ra của nó sẽ chuyển đến đầu ra của tập lệnh perl. Theo mặc định, đó là màn hình, tức là STDOUT, nhưng bạn có thể chuyển hướng nó đến bất kỳ tệp nào bằng cách sử dụng toán tử chuyển hướng> -
#!/usr/bin/perl
system( "ls -l")
1;
Khi đoạn mã trên được thực thi, nó sẽ liệt kê tất cả các tệp và thư mục có sẵn trong thư mục hiện tại -
drwxr-xr-x 3 root root 4096 Sep 14 06:46 9-14
drwxr-xr-x 4 root root 4096 Sep 13 07:54 android
-rw-r--r-- 1 root root 574 Sep 17 15:16 index.htm
drwxr-xr-x 3 544 401 4096 Jul 6 16:49 MIME-Lite-3.01
-rw-r--r-- 1 root root 71 Sep 17 15:16 test.pl
drwx------ 2 root root 4096 Sep 17 15:11 vAtrJdy
Hãy cẩn thận khi lệnh của bạn chứa các biến môi trường shell như $ PATH hoặc $ HOME. Hãy thử làm theo ba tình huống -
#!/usr/bin/perl
$PATH = "I am Perl Variable";
system('echo $PATH'); # Treats $PATH as shell variable
system("echo $PATH"); # Treats $PATH as Perl variable
system("echo \$PATH"); # Escaping $ works.
1;
Khi đoạn mã trên được thực thi, nó tạo ra kết quả sau tùy thuộc vào những gì được đặt trong biến shell $ PATH.
/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/sbin
I am Perl Variable
/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/sbin
Hàm fork ()
Perl cung cấp một fork()hàm tương ứng với lệnh gọi cùng tên của hệ thống Unix. Trên hầu hết các nền tảng giống Unix có lệnh gọi hệ thống fork (), Perl's fork () chỉ đơn giản gọi nó. Trên một số nền tảng như Windows mà lệnh gọi hệ thống fork () không khả dụng, Perl có thể được xây dựng để mô phỏng fork () ở cấp thông dịch viên.
Hàm fork () được sử dụng để sao chép một tiến trình hiện tại. Lệnh gọi này tạo ra một tiến trình mới chạy cùng một chương trình tại cùng một điểm. Nó trả về pid con cho quy trình mẹ, 0 cho quy trình con hoặc undef nếu fork không thành công.
Bạn có thể dùng exec() hàm trong một quy trình để khởi chạy tệp thực thi được yêu cầu, tệp này sẽ được thực thi trong một vùng quy trình riêng biệt và tệp execute () sẽ đợi tệp hoàn tất trước khi thoát với cùng trạng thái thoát như quy trình đó.
#!/usr/bin/perl
if(!defined($pid = fork())) {
# fork returned undef, so unsuccessful
die "Cannot fork a child: $!";
} elsif ($pid == 0) {
print "Printed by child process\n";
exec("date") || die "can't exec date: $!";
} else {
# fork returned 0 nor undef
# so this branch is parent
print "Printed by parent process\n";
$ret = waitpid($pid, 0);
print "Completed process id: $ret\n";
}
1;
Khi đoạn mã trên được thực thi, nó tạo ra kết quả sau:
Printed by parent process
Printed by child process
Tue Sep 17 15:41:08 CDT 2013
Completed process id: 17777
Các wait() và waitpid()có thể được chuyển dưới dạng ID quá trình giả được trả về bởi fork (). Các cuộc gọi này sẽ đợi đúng cách cho quá trình giả kết thúc và trả về trạng thái của nó. Nếu bạn ngã ba mà không bao giờ chờ đợi con bạn sử dụngwaitpid()chức năng, bạn sẽ tích lũy zombie. Trên hệ thống Unix, bạn có thể tránh điều này bằng cách đặt $ SIG {CHLD} thành "BỎ QUA" như sau:
#!/usr/bin/perl
local $SIG{CHLD} = "IGNORE";
if(!defined($pid = fork())) {
# fork returned undef, so unsuccessful
die "Cannot fork a child: $!";
} elsif ($pid == 0) {
print "Printed by child process\n";
exec("date") || die "can't exec date: $!";
} else {
# fork returned 0 nor undef
# so this branch is parent
print "Printed by parent process\n";
$ret = waitpid($pid, 0);
print "Completed process id: $ret\n";
}
1;
Khi đoạn mã trên được thực thi, nó tạo ra kết quả sau:
Printed by parent process
Printed by child process
Tue Sep 17 15:44:07 CDT 2013
Completed process id: -1
Hàm kill ()
Perl kill('KILL', (Process List)) có thể được sử dụng để kết thúc một quá trình giả bằng cách chuyển cho nó ID được trả về bởi fork ().
Lưu ý rằng việc sử dụng kill ('KILL', (Process List)) trên một tiến trình giả () thường có thể gây ra rò rỉ bộ nhớ, bởi vì luồng thực thi tiến trình giả không có cơ hội dọn dẹp tài nguyên của nó.
Bạn có thể dùng kill() chức năng gửi bất kỳ tín hiệu nào khác đến các quy trình đích, ví dụ như sau sẽ gửi SIGINT đến ID quy trình 104 và 102 -
#!/usr/bin/perl
kill('INT', 104, 102);
1;