نمایش پست تنها
  #1  
قدیمی 06-27-2013
دانه کولانه آواتار ها
دانه کولانه دانه کولانه آنلاین نیست.
    مدیر کل سایت
        
کوروش نعلینی
 
تاریخ عضویت: Jun 2007
محل سکونت: کرمانشاه
نوشته ها: 12,700
سپاسها: : 1,382

7,486 سپاس در 1,899 نوشته ایشان در یکماه اخیر
دانه کولانه به Yahoo ارسال پیام
پیش فرض اجرای عملیات طولانی در PHP - چگونگی برخورد با عملیاتی که مستلزم زمان اجرای زیادی هستند در زبان PHP (اختصاصي)

اجرای عملیات طولانی در PHP - چگونگی برخورد با عملیاتی که مستلزم زمان اجرای زیادی هستند در زبان PHP
Process - Execute Long Running Tasks



run a very long php script


process - How to execute long running tasks in PHP


اخیرا مشغول انجام یه پروژه هستم که یه عملیات کانورت از کدپیج ایران سیستم (فارسی قدیمی تحت داس) به یونی کد رو داخل خودش داره
واسه اسکیل کار ما و فایل ورودی حدود 320 ثانیه طول میکشه که کامل کانورت کنه اطلاعات 980 نفر از اساتید و کارمندان دانشگاهمون رو
که ذاتا زیاد نیست اما عرفا عملیاتی که یک اسکریپت انجام میده باید زیر 30 ثانیه تموم بشه و خروجی تحویل درخواست دهنده بشه
اساسا پی اچ پی زبانی هست که باید تند تند بهش درخواست بدی و درخواستو جواب بده یه زبان عملیاتی به این شکل نیست
اما به هر جهت یک جاهایی شما با این مساله دست به گریبان خواهید بود


حرفهای کلی در این مورد قبل از اینکه بخواهیم به شیوه های اصلی تر بپردازیم این هست که شما اول مطمئن بشید که اساسا اون الگوریتم و عملیاتی که مد نظرتون هست ایا به بهینه ترین حالت ممکن نوشته شده یا خیر
و اگر الگوریتمتون خوب نیست اونو بهتر کنید
گاها با نگاه کردن به کد متوجه میشید که شاید بشه با جلوگیری از یه سری دوباره کاری ها و ایجاد نکردن متغیرهای واسطه و کپی کاری های غیر ضروری سرعت رو افزایش داد
گاها هم الگوریتمهای جدیدتری برای کار مورد نظر شما ممکنه در منابع وجود داشته باشه که میتونین بهش رجوع کنین .


حالا فرض ما این هست که الگوریتم و کاری که میخواهیم بکنیم دیگه بهتر از این نمیشه و در بهترین حالت خودش به سر میبره


.


توجه داشته باشین که استفاده از توابع در عوض استفاده از کد به صورت توکار inline function زمان اجرا رو طولانی تر میکنه
یعنی اگر مجبور نیستید از یک تابع چندین بار استفاده کنید و مزایای تابع بودن خیلی براتون مهم نیست بهتره که کد اون رو به صورت inline بنویسین و از تابع استفاده نکنین و بهش متغیر ارسال و ازش نگیرید


برای مثال یک قسمت از فایل مد نظر خودم رو با ارسال به تابع کانورت طی 29 ثانیه تحویل گرفتم و با استفاده از توکار نویسی کد حدود 13 ثانیه طول کشید




امتحان کنید :


کد:
<?php function some_func() { $j = 1; } $START = time(); for ($i = 0; $i < 4000000; ++$i) { some_func(); } $END = time() - $START; echo "Calling the function took $END seconds\n"; $START = time(); for ($i = 0; $i < 4000000; ++$i) { $j = 1; } $END = time() - $START; echo "Inlining took $END seconds\n"; ?>


روی سیستم من نتیجه ش 6 ثانیه و 0 ثانیه بود .



---------------------------
چون از php.ini صحبت کردم یه بار دیگه یاد آوری کنم که به صورت دیفالت مدت زمان اجرای یک صفحه نهایتا 30 ثانیه هست و شما میتونین این مقدار رو در این فایل در قسمت
max_execution_time = 30
تغییر بدید .




--------------------
Long Running Processes


راهی که عموما پیشنهاد میشه برای این مساله , اجرا کردن اسکریپت توسط پوسته سیستم عامل هست


مثلا در محیط cmd ویندوز اون فایل php اجرا بشه یا در لینوکس در شل فایل اجرا بشه و خروجی مناسب اون رو هر کاری که دوست داشتید انجام بدید
خوبیش اینه که اولا بدون محدودیت میتونین فایل رو اجرا کنین حتی میتونه حلقه بی نهایت داشته باشه (البته در اون صورت بهتره که به صورت سرویس ارائه بشه )


در این شیوه حتی میشه به فایل ورودی پارامتر هم داد یعنی از این نظر هم مشکلی وجود نداره .



برای مثال من در ویندوز خودم از دستور


php.exe -q script.php>output.html


استفاده میکنم
و برای اینکه بتونین این نوع دستورات یا هر دستور سیستمی دیگه ای رو در داخل php استفاده کنین
میتونین از دستورات
shell_exec
system
exec
استفاده کنین (معمولا در سرورهای کانفیگ شده در فایل php.ini در بخشdisable function اینها غیر فعال شده اند )



اینجوری هر مدتی که نیاز باشه میتونه طول بکشه و شما روی پروسه ایجاد شده مدیریت خواهید داشت و
Infinite Loop

Sleepy Infinite Loop


Sleepy Definite Loop


رو خواهید داشت






__________________
مرا سر نهان گر شود زير سنگ -- از آن به كه نامم بر آيد به ننگ
به نام نكو گر بميــرم رواست -- مرا نام بايد كه تن مرگ راست



پاسخ با نقل قول
جای تبلیغات شما اینجا خالیست با ما تماس بگیرید