[Origin] ทุกคนรู้จัก daemon process (Daemon) ภายใต้ Linux/Unix เช่น httpd, mysqld ที่ใช้กันทั่วไปของเรา เป็นต้น ซึ่งเป็นโปรแกรมที่ทำงานในหน่วยความจำภายใน ซึ่งคล้ายกับบริการต่างๆ บน Windows โดยทั่วไป กระบวนการ daemon จะถูกเขียนด้วยภาษา C/C++ ซึ่งใช้เพื่อสร้างกระบวนการย่อยผ่านทางส้อม เมื่อกระบวนการหลักภายใต้เชลล์ปัจจุบันถูกฆ่า กระบวนการย่อยจะทำงานในเบื้องหลัง เพื่อไม่ให้สร้างข้อมูลเอาต์พุตบนเทอร์มินัล จะใช้ฟังก์ชันต่างๆ เช่น syslog เพื่อเขียนไฟล์บันทึก
เรารู้ว่า php เป็นภาษาสคริปต์และดำเนินการผ่านกลไกสคริปต์ php ดังนั้นจึงเป็นเรื่องยากที่จะสร้างกระบวนการ daemon วันนี้เราจะรวมคำสั่ง Unix/Linux เพื่อให้เข้าใจถึงการทำงานของกระบวนการ daemon ของเรา
[หลักการ] ฟังก์ชั่นของคำสั่ง nohup ใน Unix คือการรันคำสั่งโดยไม่ต้องวางสาย ขณะเดียวกัน nohup จะใส่เอาต์พุตทั้งหมดของโปรแกรมลงในไฟล์ nohup.out ในไดเร็กทอรีปัจจุบัน ไม่สามารถเขียนได้ แต่จะอยู่ในไฟล์ <user home directory> /nohup.out ดังนั้นหลังจากมีคำสั่งนี้ โปรแกรม php ของเราจะเขียนเชลล์สคริปต์และใช้การวนซ้ำเพื่อให้สคริปต์ของเราทำงานต่อไป ไม่ว่าหน้าต่างเทอร์มินัลของเราจะปิดหรือไม่ก็ตาม สคริปต์ php ของเราก็ยังสามารถทำงานได้ต่อไป แน่นอนว่าเมื่อกระบวนการ php ของเราถูกหยุดทำงานหรือระบบปฏิบัติการของเราถูกรีสตาร์ท มันก็จะยุติลงตามธรรมชาติ
[Function] คุณจะต้องถามอย่างแน่นอนว่าการทำให้สคริปต์ php ของเราเป็น daemon มีประโยชน์อย่างไร? แน่นอนว่ายังมีฟังก์ชันทั่วไปอยู่ด้วย ซึ่งโดยพื้นฐานแล้วสามารถแทนที่ฟังก์ชันของ cron ได้ ตัวอย่างเช่น การดำเนินการบางอย่างที่เราจำเป็นต้องดำเนินการเป็นประจำก็สามารถทำได้ และแน่นอนว่าไม่จำเป็นต้องใช้ cron อีกต่อไป เซิร์ฟเวอร์ถูกรีสตาร์ท ไม่มีทางใดเลย อย่างไรก็ตาม เซิร์ฟเวอร์ Unix ทั่วไปนั้นไม่ใช่เรื่องง่ายที่จะรีสตาร์ท นอกจากนี้ เรายังสามารถสร้างฟังก์ชันฝั่งเซิร์ฟเวอร์แบบง่ายๆ ได้ด้วย เช่น การสร้างเซิร์ฟเวอร์ที่สามารถใช้ Telnet ได้ อิอิ สามารถทำเป็นแบ็คดอร์เล็กๆ ได้ แต่การใช้งานจะซับซ้อนเล็กน้อย
[แบบฝึกหัด] ตัวอย่างที่ 1: สร้างไฟล์โดยอัตโนมัติ ตอนนี้เราจะทำสองตัวอย่างเพื่อพิสูจน์คำสั่งข้างต้น อย่างแรกเลย อย่างแรกคือสร้างไฟล์โดยอัตโนมัติทุกๆ 30 วินาทีและรันมันตลอดไป
ขั้นแรก คุณต้องแน่ใจว่าระบบปฏิบัติการเป็น Unix หรือ Linux เช่น FreeBSD, Redhat, Fedora หรือ SUSE จากนั้นเราจะต้องแน่ใจว่ากลไกสคริปต์ php ของเราอยู่ใน /usr/local/php/bin/php คุณสามารถเขียนเส้นทางเฉพาะตามเส้นทางจริงของคุณได้ หากไม่มีกลไกสคริปต์ โปรดติดตั้งด้วยตนเอง
ตัวอย่างเช่น หากไดเร็กทอรีปัจจุบันคือ /home/heiyeluren/ เราจะใช้ vi หรือโปรแกรมแก้ไขอื่นๆ เพื่อเขียนไฟล์ชื่อ php_daemon1.php:
$ vi php_daemon1.php
จากนั้นเขียนโค้ดต่อไปนี้:
#!/usr/local/php/bin/php.ini
-
set_time_limit (0);
ในขณะที่(1)
-
@fopen("test_".time().".txt","w");
นอน(30);
-
-
จากนั้นบันทึกและออกจาก vi จากนั้นให้สิทธิ์ในการปฏิบัติการไฟล์ php_daemon1.php:
$ chmod +x /home/heiyeluren/php_daemon1.php
จากนั้นให้สคริปต์ของเราดำเนินการในพื้นหลังและดำเนินการคำสั่งต่อไปนี้:
$ nohup /home/heiyeluren/php_daemon1.php &
อย่าลืมเพิ่มสัญลักษณ์ & ที่ส่วนท้ายเพื่อให้สามารถทำงานในพื้นหลังได้ หลังจากดำเนินการคำสั่งด้านบนแล้ว พรอมต์ต่อไปนี้จะปรากฏขึ้น:
[1] 82480
ต่อท้ายเอาต์พุตไปที่ nohup.out
หลังจากกลับมาที่รถแล้วจะมีข้อความแจ้งเชลล์ปรากฏขึ้น เคล็ดลับข้างต้นหมายความว่าข้อมูลเอาท์พุตของการดำเนินการคำสั่งทั้งหมดจะถูกวางไว้ในไฟล์ nohup.out ดังที่กล่าวไว้ข้างต้น หลังจากดำเนินการคำสั่งข้างต้นแล้ว เราจะเห็นไฟล์เพิ่มเติมที่ขึ้นต้นด้วย test_ ในไดเร็กทอรีปัจจุบันทุกๆ สามสิบวินาที เช่น: test_1139901144.txt test_1139901154.txt และไฟล์อื่นๆ ซึ่งพิสูจน์ว่าโปรแกรมของเรากำลังทำงานอยู่เบื้องหลัง
แล้วเราจะยุติการทำงานของโปรแกรมได้อย่างไร? วิธีที่ดีที่สุดคือการรีสตาร์ทระบบปฏิบัติการ แน่นอนว่าเราไม่แนะนำให้ใช้คำสั่ง kill เพื่อฆ่ากระบวนการ ก่อนที่จะฆ่ากระบวนการนั้น โดยปกติแล้วเราจะทราบหมายเลข PID ของกระบวนการซึ่งก็คือกระบวนการ ID คุณสามารถใช้คำสั่ง ps เพื่อดูได้
$ปล
คำสั่งเวลา PID TT STAT
82374 p3 Ss 0:00.14 -bash (ทุบตี)
82510 p3 S 0:00.06 /usr/local/php/bin/php /home/heiyeluren/php_daemon1.php
82528 p3 R+ 0:00.00 น
ข้างต้นเราได้เห็นว่ารหัสกระบวนการของ php ของเราคือ: 82510 ดังนั้นเราจึงดำเนินการคำสั่ง kill:
$ ฆ่า -9 82510
[1]+ ฆ่า nohup /home/heiyeluren/php_daemon1.php
เมื่อคุณเห็นข้อความแจ้งนี้ คุณจะรู้ว่ากระบวนการนี้ถูกหยุดทำงานแล้ว หากคุณ ps อีกครั้ง คุณจะพบว่ากระบวนการนั้นหายไปแล้ว:
$ปล
คำสั่งเวลา PID TT STAT
82374 p3 Ss 0:00.17 -bash (ทุบตี)
82535 p3 R+ 0:00.00 น
หากคุณไม่เห็นกระบวนการโดยตรงด้วยคำสั่ง ps ให้ใช้คำสั่ง ps & apos ที่รวมกันสองคำสั่งเพื่อดู และคุณจะสามารถเห็นกระบวนการได้อย่างแน่นอน
จากกระบวนการข้างต้น คุณสามารถขยายกระบวนการเพื่อสร้างโปรแกรม cron ของคุณเองได้ ดังนั้นคุณไม่จำเป็นต้องใช้ cron แน่นอน นี่เป็นเพียงวิธีเดียว ตัวอย่างที่ 2: daemon ฝั่งเซิร์ฟเวอร์ มันถูกจำลองอย่างคร่าวๆ โดยใช้ PHP ฝั่งเซิร์ฟเวอร์ จากนั้นจึงรันในพื้นหลังเพื่อให้ได้เอฟเฟกต์ของ Daemon ฝั่งเซิร์ฟเวอร์
ดำเนินการต่อในโฮมไดเร็กตอรี่ของเรา: /home/heiyeluren และแก้ไขไฟล์ php_daemon2.php:
$ vi php_daemon2.php
ป้อนรหัสต่อไปนี้ (รหัสมาจากคู่มือ PHP ฉันได้แก้ไขความคิดเห็นแล้ว):
#!/usr/local/php/bin/php.ini
<?php
/* การตั้งค่า http://www.knowsky.com/php.asp ไม่แสดงข้อผิดพลาดใดๆ*/
error_reporting(0);
/* การหมดเวลาของสคริปต์ไม่มีที่สิ้นสุด*/
set_time_limit (0);
/* เริ่มการเคลียร์แบบคงที่ */
ob_implicit_flush();
/* IP ของเครื่องนี้และพอร์ตที่ต้องเปิด */
$ที่อยู่ = '192.168.0.1';
$พอร์ต = 10,000;
/* สร้างซ็อกเก็ต */
ถ้า (($sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP)) < 0) {
echo "socket_create() ล้มเหลว: เหตุผล: " . socket_strerror($sock)
-
/* ผูกที่อยู่ IP และพอร์ต */
if (($ret = socket_bind($sock, $address, $port)) < 0) {
echo “socket_bind() ล้มเหลว: เหตุผล: ” . socket_strerror($ret)
}
/* การเชื่อมต่อซ็อกเก็ตจอภาพ */
ถ้า (($ret = socket_listen($sock, 5)) < 0) {
echo “socket_listen() ล้มเหลว: เหตุผล: ” . socket_strerror($ret)
-
/*วนซ้ำตลอดไปเพื่อตรวจสอบการเชื่อมต่อของผู้ใช้*/
ทำ {
ถ้า (($msgsock = socket_accept($sock)) < 0) {
echo "socket_accept() ล้มเหลว: เหตุผล: " . socket_strerror($msgsock)
หยุดพัก;
-
/* ส่งข้อมูลด่วนไปยังผู้ใช้ที่เชื่อมต่อ*/
$msg = “==========================================rn " .
"ยินดีต้อนรับสู่เซิร์ฟเวอร์ทดสอบ PHP rnrn"
" หากต้องการออก ให้พิมพ์ 'quit' rn"
"หากต้องการปิดเซิร์ฟเวอร์ ให้พิมพ์ 'shutdown'.rn"
"หากต้องการรับความช่วยเหลือให้พิมพ์ 'help'.rn"
"==========================================rn" .
"php>";
socket_write($msgsock, $msg, strlen($msg));
ทำ {
ถ้า (เท็จ === ($buf = socket_read($msgsock, 2048, PHP_NORMAL_READ))) {
echo “socket_read() ล้มเหลว: เหตุผล: ” . socket_strerror($ret)
พัก 2;
-
ถ้า (!$buf = ตัดแต่ง($buf)) {
ดำเนินการต่อ;
-
/*ปิดการเชื่อมต่อไคลเอนต์เมื่อไคลเอนต์เข้าสู่คำสั่งออก*/
ถ้า ($buf == 'ออก') {
หยุดพัก;
-
/* เมื่อไคลเอนต์เข้าสู่คำสั่งปิดระบบ ทั้งเซิร์ฟเวอร์และไคลเอนต์จะถูกปิดระบบ*/
ถ้า ($buf == 'ปิดเครื่อง') {
socket_close($msgsock);
พัก 2;
-
/* แสดงข้อมูลวิธีใช้เมื่อไคลเอนต์ป้อนคำสั่ง help*/
ถ้า ($buf == 'ช่วยเหลือ') {
$msg = “ข้อความช่วยเหลือเซิร์ฟเวอร์ PHP rnrn”
" หากต้องการออก ให้พิมพ์ 'quit' rn"
"หากต้องการปิดเซิร์ฟเวอร์ ให้พิมพ์ 'shutdown'.rn"
"หากต้องการรับความช่วยเหลือให้พิมพ์ 'help'.rn"
"php>";
socket_write($msgsock, $msg, strlen($msg));
ดำเนินการต่อ;
-
/*ข้อความแจ้งเตือนเมื่อไม่มีคำสั่งอินพุตไคลเอนต์*/
$talkback = “PHP: คำสั่งที่ไม่รู้จัก '$buf'.rnphp> “;
socket_write($msgsock, $talkback, strlen($talkback));
สะท้อน “$bufn”;
} ในขณะที่ (จริง);
socket_close($msgsock);
} ในขณะที่ (จริง);
/* ปิดการเชื่อมต่อซ็อกเก็ต */
socket_close($ถุงเท้า);
-
บันทึกโค้ดด้านบนแล้วออก
โค้ดข้างต้นทำให้ฟังก์ชันคล้ายกับฝั่งเซิร์ฟเวอร์ Telnet โดยคร่าวๆ นั่นคือเมื่อฝั่งเซิร์ฟเวอร์รันโปรแกรม ไคลเอนต์สามารถเชื่อมต่อกับพอร์ต 10,000 ของเซิร์ฟเวอร์เพื่อการสื่อสาร
เพิ่มสิทธิ์ปฏิบัติการให้กับไฟล์:
$ chmod +x /home/heiyeluren/php_daemon2.php
ดำเนินการคำสั่งบนเซิร์ฟเวอร์:
$ nohup /home/heiyeluren/php_daemon2.php &
มันเข้าสู่การดำเนินการเบื้องหลังและเราดำเนินการผ่าน Telnet ไคลเอนต์ Windows:
C:>เทลเน็ต 192.168.0.1 10,000
หากได้รับแจ้ง:
กำลังเชื่อมต่อกับ 192.168.0.188...ไม่สามารถเปิดการเชื่อมต่อกับโฮสต์ที่พอร์ต 10000: หากการเชื่อมต่อล้มเหลว แสดงว่าเซิร์ฟเวอร์ไม่ได้เปิดอยู่ หรือโปรแกรมข้างต้นทำงานไม่ถูกต้อง โปรดตรวจสอบว่า php มี –enable หรือไม่ - ฟังก์ชั่นซ็อกเก็ต หากได้รับแจ้ง:
-
ยินดีต้อนรับสู่เซิร์ฟเวอร์ทดสอบ PHP
หากต้องการออก ให้พิมพ์ 'ออก'
หากต้องการปิดเซิร์ฟเวอร์ให้พิมพ์ 'ปิดเครื่อง'
หากต้องการรับความช่วยเหลือให้พิมพ์ข้อความ 'help'
-
php>
ซึ่งหมายความว่าเราได้เชื่อมต่อกับ daemon ฝั่งเซิร์ฟเวอร์ที่เขียนด้วย PHP เรียบร้อยแล้ว หลังจากพร้อมท์ php> เราสามารถดำเนินการคำสั่งสามคำสั่ง เช่น help, exit และ Shutdown หากอินพุตคำสั่งไม่ใช่สามคำสั่งนี้ ระบบจะแจ้ง:
php>asdf.php>
PHP: คำสั่งที่ไม่รู้จัก 'asdf'
ดำเนินการคำสั่ง help เพื่อรับความช่วยเหลือ php> help
ข้อความช่วยเหลือเซิร์ฟเวอร์ PHP
หากต้องการออก ให้พิมพ์ 'ออก'
หากต้องการปิดเซิร์ฟเวอร์ให้พิมพ์ 'ปิดเครื่อง'
หากต้องการรับความช่วยเหลือให้พิมพ์ข้อความ 'help'
ฝั่งเซิร์ฟเวอร์นี้จะไม่ถูกนำมาใช้และสามารถขยายได้ด้วยตัวเอง
การฆ่ากระบวนการจะคล้ายกับตัวอย่างที่ 1
[สรุป] จากการเรียนรู้ข้างต้น เรารู้ว่า PHP สามารถใช้เป็นกระบวนการ daemon ได้ หากได้รับการออกแบบมาอย่างดี ฟังก์ชั่นก็จะมีประสิทธิภาพมากขึ้น อย่างไรก็ตาม เราเพียงแต่เรียนรู้ที่นี่และคุณสามารถค้นคว้าและอัปเดตได้ด้วยตัวเอง .
บทความนี้อ้างอิงถึงคู่มือ PHP ภาษาจีน การอ่านคู่มือเพิ่มเติมจะเป็นประโยชน์ต่อคุณมาก