درس 14 : آموزش برنامه نویسی Multi-threading در C++ به وسیله SDL

درس 14 : آموزش برنامه نویسی Multi-threading در C++ به وسیله SDL

 (قسمت اول)

احتمالا چیزهایی در مورد برنامه ها Multi-threaded شنیده اید یا اسم فن اوری جدید Intel به اسم Hyper-Threading را شنیده اید که اگر این فناوری بر روی CPU فعال باشد CPU جوری رفتار می کند که سیستم عامل فرض کند به جای یک CPU 4 عدد CPU در سیستم موجود است که در ان موقع اگر سیستم عامل روی این قسمت کار کرده باشد می تواند به خوبی از این خاصیت استفاده کند و مثلا اجرا برنامه ها را بین 4 CPU تقسیم کند که سرعت به طرز قابل توجهی بالا می رود فعلا که دارم این مقاله را می نویسم بین سیستم عامل هایی که برای PC موجود است Linux Fedora Core بین سیستم عامل های دیگر می تواند به بهترین نحو از چند CPU در ان واحد استفاده کند که می تواند تا حدود 60-70 % از این قابلیت استفاده کند.و البته ویندوز هم به مقدار قابل توجهی از این خاصیت پشتیبانی می کند

و در حال حاضر این خاصیت SDL در سیستم عامل MacOS X کار گذاشته نشده است به خاطر این که اساسا PCهای Macintosh تک CPU هستند و نیازی به همچین کاری احساس نمی شد.

 

به این نوع برنامه نویسی برنامه نویسی موازی هم گفته می شود که قدرت فوق العاده ای به برنامه نویس می دهد که چند کار را در یک زمان انجام دهد.

 

Thread در برنامه نویسی به پروسه ای می گویند که بخشی از یک پروسه بزرگتر یا یک برنامه باشد.

 

همانطور که گفتم برنامه نویسی Multi-threading به شما قدرت فوق العاده ای برای اجرای چند کار در یک زمان را می دهد(البته بر روی سیستم های تک CPU این یک بحث تئوری است ولی فوق العاده به درد به خور حتی در ساخت بازی) در استفاده از thread ها باید نهایت دقت را بخرج دهید.

 

یک thread هم زمان با Main برنامه شما اجرا می شود و ازدر تمام منابع  برنامه مثل فایل ها حافظه و... باmain شریک می شود و مشکل وقتی پیش می اید که یک thread در چیزی با main شریک شود که نباید با ان در Main شریک شود مثل حافظه گرافیکی یا استفاده از صدا. و چیزی که باید یادتون باشد این است که یک thread هیچ وقت از حافظه گرافیکی به طور مستقیم استفاده نکند.

 

خوب اول ببینیم چه گونه می توانیم یک thread ایجاد کنیم.

SDL_Thread *SDL_CreateThread(int (*fn)(void *), void *data);

این تابع دو پادامتر دریافت می کند یک اشاره گر به تابع و داده ای که باید تابع بپذیرد و نوع برگشتی ان هم از نوع اشاره گر به SDL_Thread است.

تابع شما شکلی مانند شکل زیر دارد

int ThreadFunction(void* data);

که این تابع یک پارامتر برای پردازش دریافت می کند و یک مقدار int برمیگرداند وقتی thread مرد این مقدار بر گشت داده می شود.

اگر به هر طریقی بخواهید یک Thread را متوقف کنید می توانید از تابع SDL_KillThread استفاده کنید یک مقدار خشن به نظر می رسد ولی تا حالا کسی پیدا نشده که از حقوق thread ها دفاع کند!!!

void SDL_KillThread(SDL_Thread *thread);

اگر می خواهید یک مقدار با حوصله تر یک thread را متوقف کنید می توانید از SDL_WaitThread استفاده کنید.

void SDL_WaitThread(SDL_Thread *thread, int *status);

این تابع یک thread را دریافت کرده و سپس یک اشاره گربه یک عدد صحیح می گیرد و منتظر اتمام کار thread می شود و مقدار برگشتی را در status قرار می دهد اگر به مقدار برگشتی اهمیتی نمی دهید می توانید مقدار NULL را به عنوان پارامتر دوم بفرستید.

 

هر thread یک ID 32 بیتی مخصوص خود است که برای مدیریت thread ها می تونید ازش استفاده کنید و به وسیله فراخوانی تابع SDL_ThreadID درون thread می توانید مقدار ان را بیابید.

Uint32 SDL_ThreadID(void);

البته اگر بخواهید از بیرون Thread شناسه ان را بدست اورید می توانید از تابع زیر استفاده کنید.

Uint32 SDL_GetThreadID(SDL_Thread *thread);

 

نکته : برای استفاده از thread ها حتما باید فایل SDL_Thread.h را بارگزاری نمایید و در thread ها نیازی به استفاده از SDL_Init نیز وجود ندارد.

 

MUTEX:

موتکس راه ساده ای برای بر قرار کردن ارتباط بین Thread ها است و یکی از این دو حالت رو به خودش می گیرد Locked و Unlocked . وقتی یک موتکس به وسیله یک thread قفل می شود و thread دیگری خواهان قفل کردن Mutex می شود باید منتظر بماند تا thread قبلی ان را از حالت قفل بیرون بیاورد.

شما به راحتی می توانید بوسیله تابعSDL_CreateMutex  یک Mutex بسازید.

SDL_mutex *SDL_CreateMutex(void);

این تابع هیچ پارامتری نمی گیرد و یک اشاره گر به SDL_mutex بر می گرداند.

برای نابود کردن یک موتکس هم می توانید از تابعSDL_DestroyMutex استفاده کنید

void SDL_DestroyMutex(SDL_mutex *mutex);

 

شما همچنین می توانید به وسیله تابع SDL_MutexP یا ماکرو SDL_LockMutex یک موتکس را قفل کنید.

int SDL_mutexP(SDL_mutex *mutex);

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

همچنین از تابع SDL_mutexV می توانید برای ازاد کردن یک موتکس استفاده کنید.

int SDL_mutexV(SDL_mutex *mutex);

یا ازمیتوانید از ماکرو SDL_UnlockMutex استفاده کنید.

یک نمونه ساده ولی جالب از استفاده از Mutex :

 

g_pMutex=SDL_CreateMutex();

SDL_LockMutex(g_pMutex);

g_pThread=SDL_CreateThread(ThreadFunction,NULL);

SDL_UnlockMutex(g_pMutex);

SDL_WaitThread(g_pThread,NULL);

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

تابع thread مان هم به شرح زیر است.

int ThreadFunction(void* data)

{

    fprintf(stdout,”Thread %d: Initialized! ”,SDL_ThreadID());

    fprintf(stdout,”Thread %d: Attempting to lock mutex. ”,SDL_ThreadID());

    SDL_LockMutex(g_pMutex);

    fprintf(stdout,”Thread %d: Mutex is locked. ”,SDL_ThreadID());

    fprintf(stdout,”Thread %d: Unlocking mutex. ”,SDL_ThreadID());

    SDL_UnlockMutex(g_pMutex);

    fprintf(stdout,”Thread %d: Terminating. ”,SDL_ThreadID());

    return(0);

}

این تابع کار خهصی انجام نمی دهد غیر از دادن گزارش کار به ما; در ابتدای کار سعی میکند موتکس را قفل کند ولی چون قبلا قفل شده می ایستد تا ازاد شود سپس قفل میکند و ازاد می کند و متوقف می شود.

نظرات 2 + ارسال نظر
هیچ یکشنبه 29 مرداد‌ماه سال 1385 ساعت 02:31 ق.ظ http://no-one.blogsky.com

سلام. آقا لینک دانلود visual studio رو نداری؟ البته مطمئنا مجانیش دیگه ؛)
ممنون

صابر پنج‌شنبه 26 بهمن‌ماه سال 1385 ساعت 12:50 ب.ظ http://sabersoft.blogsky.com

سلام وبلاگ خوبی داری من هم در وبلاگم به طراحی بازی با ژاسکال می پردازم به من هم سر بزن اگر مایل باشید با هم تبلدل لینک کنیم

برای نمایش آواتار خود در این وبلاگ در سایت Gravatar.com ثبت نام کنید. (راهنما)
ایمیل شما بعد از ثبت نمایش داده نخواهد شد