Perl - การจัดการกระบวนการ

คุณสามารถใช้ Perl ในรูปแบบต่างๆเพื่อสร้างกระบวนการใหม่ตามความต้องการของคุณ บทช่วยสอนนี้จะแสดงรายการวิธีการสร้างและจัดการกระบวนการ Perl ที่สำคัญและใช้บ่อยที่สุด

  • คุณสามารถใช้ตัวแปรพิเศษ $$ หรือ $PROCESS_ID เพื่อรับ ID กระบวนการปัจจุบัน

  • ทุกกระบวนการที่สร้างขึ้นโดยใช้วิธีการใด ๆ ที่กล่าวถึงจะรักษาสภาพแวดล้อมเสมือนของตัวเองไว้ในตัว %ENV ตัวแปร.

  • exit() ฟังก์ชันจะออกจากโปรเซสลูกเสมอซึ่งรันฟังก์ชันนี้และโปรเซสหลักโดยรวมจะไม่ออกเว้นแต่โปรเซสลูกที่รันอยู่ทั้งหมดจะออก

  • แฮนเดิลที่เปิดอยู่ทั้งหมดเป็น dup () - ed ในกระบวนการย่อยดังนั้นการปิดแฮนเดิลใด ๆ ในกระบวนการเดียวจะไม่ส่งผลกระทบต่ออื่น ๆ

ตัวดำเนินการ Backstick

วิธีที่ง่ายที่สุดในการเรียกใช้คำสั่ง Unix คือการใช้ตัวดำเนินการ backstick คุณเพียงแค่ใส่คำสั่งของคุณไว้ในตัวดำเนินการ backstick ซึ่งจะส่งผลให้มีการดำเนินการคำสั่งและส่งคืนผลลัพธ์ซึ่งสามารถจัดเก็บได้ดังนี้ -

#!/usr/bin/perl

@files = `ls -l`;

foreach $file (@files) {
   print $file;
}

1;

เมื่อโค้ดด้านบนถูกเรียกใช้งานจะแสดงรายการไฟล์และไดเร็กทอรีทั้งหมดที่มีอยู่ในไดเร็กทอรีปัจจุบัน -

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

ระบบ () ฟังก์ชั่น

คุณยังสามารถใช้ system()ฟังก์ชันเพื่อดำเนินการคำสั่ง Unix ซึ่งเอาต์พุตจะไปที่เอาต์พุตของสคริปต์ perl โดยค่าเริ่มต้นจะเป็นหน้าจอเช่น STDOUT แต่คุณสามารถเปลี่ยนเส้นทางไปยังไฟล์ใดก็ได้โดยใช้ตัวดำเนินการเปลี่ยนเส้นทาง> -

#!/usr/bin/perl

system( "ls -l")

1;

เมื่อโค้ดด้านบนถูกเรียกใช้งานจะแสดงรายการไฟล์และไดเร็กทอรีทั้งหมดที่มีอยู่ในไดเร็กทอรีปัจจุบัน -

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

ระวังเมื่อคำสั่งของคุณมีตัวแปรสภาพแวดล้อมเชลล์เช่น $ PATH หรือ $ HOME ลองทำตามสามสถานการณ์ -

#!/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;

เมื่อโค้ดด้านบนถูกเรียกใช้งานจะสร้างผลลัพธ์ต่อไปนี้ขึ้นอยู่กับสิ่งที่กำหนดไว้ในตัวแปรเชลล์ $ 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

ส้อม () ฟังก์ชั่น

Perl ให้ fork()ฟังก์ชันที่สอดคล้องกับการเรียกระบบ Unix ที่มีชื่อเดียวกัน บนแพลตฟอร์มที่เหมือน Unix ส่วนใหญ่ที่มีการเรียกใช้ระบบ fork () Perl's fork () เรียกมันว่า ในบางแพลตฟอร์มเช่น Windows ที่ไม่สามารถใช้การเรียกระบบ fork () Perl สามารถสร้างขึ้นเพื่อเลียนแบบ fork () ในระดับอินเตอร์พรีเตอร์

ฟังก์ชัน fork () ใช้เพื่อโคลนกระบวนการปัจจุบัน สายนี้สร้างกระบวนการใหม่ที่เรียกใช้โปรแกรมเดียวกัน ณ จุดเดียวกัน ส่งคืน pid ลูกไปยังกระบวนการหลัก 0 ไปยังกระบวนการลูกหรือ undef ถ้าส้อมไม่สำเร็จ

คุณสามารถใช้ได้ exec() ฟังก์ชันภายในกระบวนการเพื่อเรียกใช้โปรแกรมปฏิบัติการที่ร้องขอซึ่งจะดำเนินการในพื้นที่กระบวนการที่แยกจากกันและ exec () จะรอให้ดำเนินการเสร็จสิ้นก่อนที่จะออกโดยมีสถานะออกเช่นเดียวกับกระบวนการนั้น

#!/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;

เมื่อโค้ดด้านบนถูกเรียกใช้งานจะให้ผลลัพธ์ดังนี้ -

Printed by parent process
Printed by child process
Tue Sep 17 15:41:08 CDT 2013
Completed process id: 17777

wait() และ waitpid()สามารถส่งผ่านเป็นรหัสกระบวนการหลอกที่ส่งคืนโดย fork () การโทรเหล่านี้จะรอการยุติกระบวนการหลอกอย่างถูกต้องและส่งคืนสถานะ หากคุณคีบโดยไม่ต้องรอให้ลูกใช้waitpid()คุณจะสะสมซอมบี้ ในระบบ Unix คุณสามารถหลีกเลี่ยงปัญหานี้ได้โดยตั้งค่า $ SIG {CHLD} เป็น "IGNORE" ดังนี้ -

#!/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;

เมื่อโค้ดด้านบนถูกเรียกใช้งานจะให้ผลลัพธ์ดังนี้ -

Printed by parent process
Printed by child process
Tue Sep 17 15:44:07 CDT 2013
Completed process id: -1

ฟังก์ชัน kill ()

Perl kill('KILL', (Process List)) ฟังก์ชันสามารถใช้เพื่อยุติกระบวนการหลอกโดยส่ง ID ที่ส่งคืนโดย fork ()

โปรดทราบว่าการใช้ kill ('KILL', (รายการกระบวนการ)) บนกระบวนการหลอก () โดยทั่วไปอาจทำให้หน่วยความจำรั่วไหลเนื่องจากเธรดที่ใช้กระบวนการหลอกไม่ได้รับโอกาสในการล้างทรัพยากร

คุณสามารถใช้ได้ kill() ฟังก์ชันเพื่อส่งสัญญาณอื่น ๆ ไปยังกระบวนการเป้าหมายตัวอย่างเช่นต่อไปนี้จะส่ง SIGINT ไปยังรหัสกระบวนการ 104 และ 102 -

#!/usr/bin/perl

kill('INT', 104, 102);
 
1;