تعدد العمليات في PHP غائب "خارج الصندوق" ، لذلك تم اختراع العديد من الخيارات لتنفيذه ، بما في ذلك
pthreads ملحقات ،
AzaThread (CThread) ، وحتى بعض التطورات
الخاصة مطوري PHP.
كان العيب الرئيسي بالنسبة لي الكثير من "أجراس وصفارات" لهذه الحلول - ليست هناك حاجة دائما لتبادل المعلومات بين المواضيع وعملية الأصل أو لتوفير الموارد. يجب أن يكون هناك دائمًا القدرة على حل المشكلة بسرعة وفعالية من حيث التكلفة.
أريد أن أبدي تحفظًا مقدمًا بأن الأسرار العظيمة لا تفتح في هذا المنشور - فمن المرجح للمبتدئين في اللغة ، وقررت أن أنشرها فقط لأنني واجهت مشكلة بنفسي ، ولأنني لم أجد حلاً جاهزًا ، فقد قمت بنوع من مضاهاة مؤشرات الترابط المتعددة بنفسي.
لذلك ، تتمثل المهمة في معالجة كمية كبيرة من البيانات التي جاءت في برنامجنا النصي. كانت مهمتي هي معالجة مجموعة JSON من المعلومات النصية ، وهضم البرنامج النصي الذي كان عليه جمع التزام كبير بنفس القدر لـ PostgreSQL.
بادئ ذي بدء ، نجمع البيانات في الملف الأصل:
index.php
تذبذب حجم الصفيف حوالي 400 ميجابايت (تم تخفيضه لاحقًا إلى 50 ميجابايت تقريبًا) ، وكانت جميع المعلومات نصية. ليس من الصعب تقدير السرعة التي تم هضمها بالكامل ، وبالنظر إلى أن البرنامج النصي كان يتم تشغيله على cron كل 15 دقيقة ، وأن قوة الحوسبة كانت كذلك - فقد تأثر الأداء كثيرًا.
بعد تلقي البيانات ، يمكنك تقدير حجمها ، وإذا لزم الأمر ، قم بحساب العدد المطلوب من سلاسل العمليات لكل نواة وحدة المعالجة المركزية ، أو يمكنك ببساطة تحديد أنه سيكون هناك 4 سلاسل رسائل وحساب عدد الصفوف لكل سلسلة رسائل:
index.php
تجدر الإشارة إلى ذلك على الفور - مثل هذا الحساب "المباشر" لن يعطي نتيجة دقيقة بعدد العناصر لكل تيار. هناك حاجة على الأرجح لتبسيط العمليات الحسابية.
والآن جوهر الأمر - نقوم بإنشاء مهام لكل مؤشر ترابط وتشغيله. سنفعل هذا "الجبين" - إنشاء مهمة للملف الثاني - thread.php. سيكون بمثابة "دفق" ، ويتلقى مجموعة من العناصر للمعالجة والبدء بشكل مستقل عن البرنامج النصي الرئيسي:
index.php
يتم استخدام وظيفة
passthru () لتشغيل أوامر وحدة التحكم ، ولكن سينتظر البرنامج النصي حتى يكتمل كل منهم. للقيام بذلك ، نقوم بلف أمر التشغيل في مجموعة من العبارات التي ستبدأ العملية ولن تُرجع أي شيء على الفور ، ولن تبدأ العملية الأصل ولن تنتظر انتظار تنفيذ كل طفل:
ما يحدث بالضبط هنا ، لسوء الحظ ، لا أستطيع أن أقول على وجه اليقين - لقد اقترح لي Linuxoid مجموعة من المعلمات. إذا أمكنك فك رموز هذا السحر في التعليقات ، سأكون ممتنًا وسأكمل النشر.
ملف thread.php:
$start = $argv[1]; $stop = $argv[2]; for ($i = $start; $i <= $stop; $i++) {
في هذه الطريقة البسيطة للغاية ، يمكنك تنفيذ مضاهاة مؤشرات ترابط متعددة في PHP.
إذا قمنا بتقليل المثال بأكمله إلى ناتج جاف ، فأعتقد أنه سيبدو كما يلي: يقوم مؤشر الترابط الأصل من خلال سطر الأوامر بإطلاق العمليات الفرعية وإخبارهم بالمعلومات المطلوب معالجتها.
عندما أقول "مضاهاة" ، أعني أنه مع طريقة التنفيذ هذه ، لا توجد طريقة لتبادل المعلومات بين سلاسل الرسائل أو بين سلاسل المفاتيح الأصل والطفل. إنه مناسب إذا كان معروفًا مسبقًا أن هذه الميزات غير مطلوبة.