กำลังใช้มัลติเธรดใน PHP หรือไม่ เมื่อคุณเห็นชื่อนี้ คุณต้องคิดว่าฉันบ้าไปแล้ว... แต่จริงๆ แล้ว
นี่คือวิธีการบางอย่างของฉันที่ผ่านการทดสอบแล้ว
เรารู้
ดีตัว PHP นั้นไม่รองรับการทำงานแบบมัลติเธรด แต่เว็บเซิร์ฟเวอร์ของเรารองรับ
การทำงานแบบมัลติเธรดใน PHP
สมมติว่าเรากำลังเรียกใช้ไฟล์ a.php ตอนนี้แต่
ฉันก็ขอให้เว็บเซิร์ฟเวอร์รัน b.php อื่นในโปรแกรมด้วย
ดังนั้นทั้งสองไฟล์จะถูกดำเนินการพร้อมกัน
(PS: หลังจากคำขอลิงก์ ถูกส่งไปแล้วเว็บเซิร์ฟเวอร์จะดำเนินการไม่ว่าไคลเอนต์จะออกแล้วก็ตาม )
บางครั้งสิ่งที่เราต้องการเรียกใช้ไม่ใช่ไฟล์อื่น แต่เป็นส่วนหนึ่งของโค้ดในไฟล์นี้เราควรทำ
อย่างไร สามารถใช้พารามิเตอร์เพื่อควบคุมโปรแกรม a.php ที่จะรัน
ได้ นี่คือตัวอย่าง:
//a .php
รหัส PHP:--------------------------------------------------- - ----------------------------------
<?php
ฟังก์ชั่น runThread()
-
$fp = fsockopen('localhost', 80, $errno, $errmsg);
fputs($fp, "GET /a.php?act=brnrn"); // พารามิเตอร์ตัวที่สองที่นี่คือส่วนหัวคำขอที่ระบุในโปรโตคอล HTTP
//หากไม่เข้าใจ โปรดดูคำจำกัดความใน RFC
fclose($fp);
}
ฟังก์ชัน ก()
-
$fp = fopen('result_a.log', 'w');
fputs($fp, 'Set in ' . Date('h:i:s', time()) . (double)microtime() . "rn");
fclose($fp);
}
ฟังก์ชัน ข()
-
$fp = fopen('result_b.log', 'w');
fputs($fp, 'Set in ' . Date('h:i:s', time()) . (double)microtime() . "rn");
fclose($fp);
}
if(!isset($_GET['act'])) $_GET['act'] = 'a';
ถ้า($_GET['การกระทำ'] == 'a')
-
runThread();
ก();
-
อย่างอื่นถ้า($_GET['act'] == 'b') b();
?>
------------------------------------------------ --------------------------------
เปิด result_a.log และ result_b.log และเปรียบเทียบเวลาการเข้าถึงของทั้งสองไฟล์ คุณจะพบว่าทั้งสองไฟล์ทำงานในเธรดที่แตกต่างกัน
บางครั้งมันก็เหมือนกันทุกประการ
ข้างต้นเป็นเพียงตัวอย่างง่ายๆ และคุณสามารถปรับปรุงเป็นรูปแบบอื่นๆ ได้
แล้ว
เกิดปัญหาขึ้น นั่นคือ การซิงโครไนซ์ เรารู้ว่า PHP เองไม่รองรับมัลติเธรด
1.
พยายามอย่าเข้าถึงทรัพยากรเดียวกันเพื่อหลีกเลี่ยงข้อขัดแย้ง แต่คุณสามารถใช้งานฐานข้อมูลได้ในเวลาเดียวกัน เนื่องจากฐานข้อมูลรองรับการทำงานพร้อมกันอย่าเขียนข้อมูลลงในไฟล์เดียวกัน
ใน PHP แบบมัลติเธรด
ต้องการเขียนใช้วิธีการอื่นในการซิงโครไนซ์ เช่น เรียกฝูงเพื่อล็อคไฟล์ ฯลฯ หรือสร้างไฟล์ชั่วคราวและรอให้ไฟล์หายไปในเธรดอื่น while(file_exits('xxx')); เทียบเท่ากับ เมื่อไฟล์ชั่วคราวนี้มีอยู่ แสดงว่าเธรดกำลังทำงานอยู่
หากไม่มีไฟล์ดังกล่าว แสดงว่าเธรดอื่นได้เผยแพร่ไปแล้ว
2. พยายามอย่าอ่านข้อมูลจากซ็อกเก็ตนี้หลังจาก runThread ดำเนินการ fputs บรรลุ multi-threading จำเป็นต้องใช้โหมด non-blocking นั่นคือจะกลับมาทันทีเมื่อใช้ฟังก์ชัน
เช่น
fget ดังนั้นจะเกิดปัญหาเมื่ออ่านและเขียนข้อมูลหากใช้โหมดการบล็อก ไม่ใช่แบบมัลติเธรด ต้องรอการส่งคืนข้างต้นก่อนจึงจะรันโปรแกรมต่อไปนี้ได้ ดังนั้นหากคุณต้องการแลกเปลี่ยนข้อมูล ในที่สุดคุณก็สามารถใช้ไฟล์หรือข้อมูลภายนอกเพื่อทำให้เสร็จได้ $fp) เพื่อให้บรรลุเป้าหมาย
ต้องบอกว่าสิ่งนี้มีความสำคัญในทางปฏิบัติหรือไม่ เมื่อใดที่จำเป็นต้องใช้วิธีนี้
คำตอบคือใช่ ดังที่เราทุกคนทราบกันดีว่าในแอปพลิเคชันที่อ่านทรัพยากรเครือข่ายอย่างต่อเนื่อง ใช้วิธีนี้สามารถ
อ่านหน้าต่างๆ หลายๆ กระทู้ได้พร้อมๆ กัน
ผมได้สร้างโปรแกรมที่สามารถค้นหาข้อมูลจากเว็บไซต์ห้างสรรพสินค้า เช่น 8848 และ soaso นอกจากนี้ยังมีโปรแกรมที่อ่านข้อมูลทางธุรกิจและไดเร็กทอรีบริษัทจากเว็บไซต์อาลีบาบาและยังใช้
เทคโนโลยีนี้
อีกด้วยเนื่องจากทั้งสองโปรแกรมต้องเชื่อมต่อกับเซิร์ฟเวอร์อย่างต่อเนื่องเพื่ออ่านข้อมูลและบันทึกลงในฐานข้อมูล การใช้เทคโนโลยีนี้จะช่วยลดปัญหาคอขวดในการรอคำตอบ