تعداد بازدید: 186

اجرای برنامه Blocking , None Blocking

مفسر های زبان های برنامه نویسی به دو نوع blocking , none blocking عمل می کنند. نحوه پردازش مفسر در زبان برنامه نویسی روی نحوه ساختار کدها تاثیر می گذارد و ممکن است بسته به نوع عملکرد Blocking , None Blocking متقاوت عمل کنید. مهم ترین موضوع برای پردازش های None Blocking این است که چگونه پس نیاز های این پردازش ( در اصطلاح Callback ها ) را اعمال کنیم.

Blocking Mode

حالت Blocking Mode به این شکل است که پردازش جاری پردازش های آتی را تا پایان پردازش فعلی بلاک می کنند. زبان PHP به این شکل این پردازش ها را مدیریت می کند:

function async_process(){
    for($i=0;$i<10;$i++){
        echo "{$i},";
        sleep(1);
    }   
}

echo "start,";
async_process();
echo 'end';
/* start,0,1,2,3,4,5,6,7,8,9,end */

در مثال بالا می بینید با این که تابع async_process حداقل ۱۰ ثانیه برای اجرا نیاز دارد باز هم رشته end در آن چاپ نمی شود تا پایان اجرای این تابع.

ویژگی اجرای مفسر ها به صورت Blocking Mode :

  • پردازش های به صورت خط به خط اتفاق می افتد
  • پردازش ها به صورت Synchronous اجرا می گردد و پردازش ها در جایگاه صحیح خود اجرا می شوند.
  • جریان پردازش فعلی مانع از اجرای پردازش های آتی خود است.
  • تا برنگشتن نتیجه صحت یا عدم صحت تابع برای اجرا به خط بعد نمی رود.

 

synchron process

به این شکل از پردازش پردازش sequential نیز می گوییم

همان طور که در پردازش های بالا مشاهده می کنید پردازش شماره ۳ با این که زمان بیشتری نسبت به سایر پردازش ها می برد تا پایان آمدن صحت یا عدم صحت آن پردازش شماره ۴ اجرا نمی شود و ما عملا نتیجه هر پردازش را در پردازش بعدی داریم و این روال به این شکل است که پردازش جاری مانع اجرای پردازش آتی خود خواهد شد.

None Blocking Mode

حالت None Blocking Mode به این شکل است که پردازش فعلی پردازش های آتی را بلاک نمی کند و آن را در یک stack برای اجرا نگه می دارد و برای اجرا به سایر خط های کد می رود. زبان جاوا اسکریپت یک زبان None Blocking Mode است.

function asyncProcess(){                                                                                                                                                                                          
    setTimeout(() => {                                                                                                                                                                                            
        console.log('it work')                                                                                                                                                                                    
    },3000)                                                                                                                                                                                                       
}                                                                                                                                                                                                                                                                                                                                                                                                                      
console.log('start')                                                                                                                                                                                              
asyncProcess()                                                                                                                                                                                                    
console.log('end')
/*
start
end
it work
*/

در بلوک کد بالا همان طور که مشاهده می کنید اجرای تابع asyncProcess مانع اجرای خط کد end نشده است و روال خروجی این بلوک کد گویای عملکرد None Blocking Mode است.

رفتار مفسر ها در اجرا به صورت None Blocking :

  • پردازش ها به صورت Asynchronous یعنی خارج از جریان برنامه اجرا می گردد.
  • نتیجه خروجی باکس کد ممکن است مطابق با خطوط کد ها در جریان برنامه نباشد.
  • اگر یک تابع اجرا گردد تا آمدن پاسخ صبر نمی کند و مستقیم به خط بعدی برای اجرا می رود و طبیعتا اگر تابع زمان زیادی برای اجرا نیاز داشت ممکن است نتیجه را پس از خط بعدی خود داشته باشد.

تصویر زیر از نحوه پردازش به صورت Asynchronous یا همان None Blocking می باشد. همان طور که می بینید مفسر تا رسیدن به پردازش asynch آن را راه اندازی و به پزدازش بعد می رود. پس ما نتیجه پردازش سوم را در خط پردازش چهارم نخواهیم داشت.

پردازش ناهمگام

به این شکل از پردازش concurrent نیز می گوییم.

این عبارات را در رابطه با نحوه اجرای توابع در خاطر بسپارید:

  • Blocking/Node Blocking Mode : پردازش ها مانع اجرای پردازش های آتی بشوند یا خیر
  • Asynchronous / Synchronous : این که پردازش های به صورت همگام اجرا شوند یا خارج از جریان اجرای برنامه یا ناهماهنگ یا ناهمگام
  • Sequential / Concurrent : به صورت یکجا شروع شوند یا به صورت پشت سرهم.

Asynchronous Process

معمولا پردازش های ناهمگام رفتاری متفاوت در مفسر ایجاد می کند و می توان گفت مدیریت این پردازش ها متفاوت است در مفسر هایی با None Blocking . یکی از بزرگترین چالش ها در در رفتار با این گونه پردازش ها اجرای Callback های لازم پس از اجرای تابع Asynchronous می باشد. همان طور که می دانید زمان پایان اجرای پردازش ناهمگام در جریان برنامه مشخص نیست همچنین ما نتیجه پردازش را در خطوط بعد نداریم .

بلوک کد زیر یک نمونه پردازش Synchronous می باشد . پس از اجرای قطعه کد زیر آن با به وسیله تابع setTimeout به روش Asynchronous اجرا می کنیم و مشکلات پیش روی آن را به وسیله Promise , Callback برطرف می کنیم:

function asyncProcess(){                                                                                                                                                                                          
    return 'abolfazl'                                                                                                                                                                                     
}                                                                                                                                                                                                                                                                                                                                                                                                                          
var name = asyncProcess()                                                                                                                                                                                                    
console.log(name) //abolfazl

یکی از معروف ترین پردازش های ناهمگام در جاوا اسکریپت Ajax یا همان Asynchronous Javascript XML و تابع setTimeout می باشد.

function asyncProcess(){                                                                                                                                                                                          
    setTimeout(() => {                                                                                                                                                                                            
        var name = 'abolfazl'                                                                                                                                                                                     
    },3000)                                                                                                                                                                                                       
}                                                                                                                                                                                                                                                                                                                                                                                                                          
asyncProcess()                                                                                                                                                                                                    
console.log(name) //Reference Error: name is undefined

در بلوک کد بالا ما با این که متغیر name را در تابع asyncProcess تعریف کرده ایم اما به دلیل اجرای None Blocking ما نتیجه تابع asyncProcess را دقیقا بعد از اجرای این تابع نداریم. برای حل این موضوع می توانیم از callback استفاده کنیم:

function asyncProcess(callback){                                                                                                                                                                                  
    setTimeout(() => {                                                                                                                                                                                            
        var name = 'abolfazl'                                                                                                                                                                                     
        callback(name)                                                                                                                                                                                            
    },3000)                                                                                                                                                                                                       
}                                                                                                                                                                                                                                                                                                                                                                                                                           
asyncProcess((name) => { console.log(name) })

در قطعه کد بالا ما مقدار name را در این callback داریم و به درستی و بدون خطا این مقدار چاپ می گردد. یکی دیگر از روش های مدیریت توابع Asynchronous اجرای توابع به صورت Promise Based است . به شکلی که ما باید یک Promise به جای مقدار اصلی برگردانیم ( Proxy Design Pattern ) .

function asyncProcess(){                                                                                                                                                                                          
    return new Promise( (resolve,reject) => {                                                                                                                                                                     
        setTimeout(() => {                                                                                                                                                                                        
            resolve('abolfazl')                                                                                                                                                                                   
        },3000)                                                                                                                                                                                                   
    })                                                                                                                                                                                                            
}                                                                                                                                                                                                                 
                                                                                                                                                                                                                  
asyncProcess()                                                                                                                                                                                                    
.then( (name) => {                                                                                                                                                                                                
    console.log(name)                                                                                                                                                                                             
})

در قطعه کد بالا ما پس از اجرای asyncProcess می توانیم تابع شخصی خود را به آن متصل کنیم. مقدار ورودی این تابع در Promise constructor execution تعیین شده است که همان نام abolfazl است.

مطالب مشابه

Obeject Data Structure in JavaScript

هر زبان برنامه نویسی از دو ساختار اصلی تشکیل شده است . بخش اول (Data Structure) ساختمان های داده آن و بخش دوم لیست...

اشتراک گذاری :

مدیر وب سایت گنوتک . برنامه نویسی رو با زبان C در هفده سالگی شروع کردم . در حال حاضر به برنامه نویسی php برپایه معماری MVC , HMVC و همچنین سیستم مدیریت محتوای WordPress و فریم ورک محبوب لاراول علاقه مند هستم و دوست دارم اطلاعاتم رو با شما به اشتراک بگذارم.

۰ دیدگاه برای اجرای برنامه Blocking , None Blocking

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *