آموزش برنامه نویسی C/C++برنامه نویسیتازه ها

کاربرد کلمه کلیدی volatile در زبان C

این مطلب رو از سایت های زیر نقل می کنم:

مطلب سایت الگوریتم ها خیلی جالب و مفید است توصیه می کنم حتما بخونینش

کاربرد کلمه‌ی کلیدی volatile:

متغیرهایی از نوع volatile متغیرهایی هستند که ممکن است مقدار آنها توسط یک پردازش خارجی تغییر یابد. این پردازش می‌تواند وقوع یک وقفه، یا تغییر از طریق یک پردازش موازی باشد. کامپایلرهای زبان برنامه‌نویسی ++C اغلب از روش‌های بهینه‌سازی برای دست‌یابی به متغیرهای تعریف شده در طول برنامه استفاده می‌کنند. به عنوان مثال، آخرین تغییر هر متغیر در طول پردازش را به عنوان مقدار آن متغیر در نظر گرفته و اگر دستوری مقدار متغیر را تغییر ندهد، همان مقدار نهایی را در پردازش مدنظر قرار می‌دهد. اما متغیرهایی از نوع volatile متغیرهایی هستند که لزوما از طریق پردازش جاری تغییر نمی‌کنند. بنابراین ممکن است مقدار آنها توسط پردازش دیگر یا یک وقفه عوض شود، بدون آنکه کامپایلر متوجه باشد. برای جلوگیری از چنین خطایی، کلمه‌ی کلیدی volatile در ابتدای تعریف متغیر استفاده می‌شود، تا کامپایلر عملیات بهینه‌سازی روی آن انجام نداده و در هر بار فراخوانی اسم متغیر در طول برنامه، مقدار آن را از محل حافظه بخواند.

volatile int Item;
int WaitForChange()
{
    Item = 0;
    while(!Item); // حلقه با بدنه‌ی تهی
    return Item;
}

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

منظور از volatile تو code vision چیه؟

Volatile  به معنای مقیم باعث می شه که از رجیستر های CPU که همون R0 تا R31 هستند استفاده نکنه و متغیر رو در فضای SRAM قرار بده .
همونطور که می دونید در زبان اسمبلی اگر متغیری در فضای SRAM باشه کامپیایلر  بخواد از اون متغیر استفاده کنه ، اول باید اون متغیر رو به یکی از رجیستر های سی پی یو(به عنوان مثال R2) انتقال بده  و بعد از اون از متغیر برای انتقال ، مقایسه یا هر منظور دیگری استفاده کنه .. اگر از Volatile برای تعریف متغیر استفاده نکرده باشید و مجددا  از این متغیر استفاده کنید ، کامپایلر دوباره مقدار متغیر را از SRAM نمیخونه و مستقیما از رجیستر CPU مجددا استفاده می کنه ، هر چند که ممکنه قبل از اون مقدار متغیر در SRAM تغییر کرده باشه ولی در رجیستر CPU مقدار همون مقدار قبلی باشه .
قرار دادن Volatile در هنگام تعریف متغیر باعث میشه با هر بار استفاده از متغیر ، کامپایلر مستقیما از فضای اختصاص داده شده از SRAM مقدار جدید رو بگیره و تغییرات مقدار متغیر در قسمتهای دیگر برنامه تشخیص داده بشه .
اگر حجم رم مورد نیاز برنامه کم باشه و عبارت Volatile  رو قرار ندید ، کامپایلر از رجیستر های CPU برا اختصاص فضا به متغیر استفاده می کنه که مشکل فوق به وجود نمیاد  ولی اگر برنامه حجیم تر بشه و فضای RAM بیشتری نیاز باشه ، کامپایلر مجبوره که از فضای SRAM برای بعضی از متغیر ها استفاده کنه ، که اگر هنگام تعریف این متغیر ها از volatile  استفاده نکنید ، به مشکل فوف بر می خورید( مثلا گیر کردن برنامه توی یک While )(در این حالت برای نوشتن در متغیر از حافظه ی SRAM استفاده می شه و برای خواندن از متغیر از رجیستر CPU استفاده میشه )
 آقا هادی هم مطلب زیر رو تذکر دادن که من اضافه می کنم به مطلب ممنون از راهنماییشون:
دوست عزیز.
ممنون از وبسایت بسیار خوب و پر محتواتون
متغیر های Volatile در کامپایلر Keil بیشتر زمان هایی استفاده میشه که شما دو تا سورس کد داشته باشی و بخوای یک متغیر رو در هر دو سورس کد استفاده کنی.برای همین توی یک سورس اون متغیر رو Volatile  و تو سورس کد بعدی که همه مربوط به یک پروژه واحد هستن اون متغیر ور extern تعریف میکنیتو کدویژن volatile رو زمانی بهتره استفاده کنین که بخواین یک متغیر عمومی رو توی برنامه سرویس وقفتون مقدار دهی کنین.این حالت بیشتر تو زمان هایی بوجود میاد که تابع مربوط به وقفه شما بعد از تابع main صدا زده بشه و یا تو پروژه هایی که چند سورس دارین.تو این حالت ها بدلیل بهینه کردن کد ، کامپایلر در نظر میگیرد که این متغییر دیگر تغییری نمیکند به همین علت در برنامه اصلی آن را دوباره فراخوانی نمیکند و از رجیستر عمومی خود کمک میگیرد تا کد بهینه تر شود.بهتره همیشه متغیر های عمومی که توی برنامه وقفه عمومیتون استفاده میشن رو از جنس volatile تعریف کنین تا این مشکل بوجود نیاد.البته این مشکل بیشتر تو وقفه های بعد از main بوجود میاد.
موفق باشید

علی عزتی

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

نوشته های مشابه

4 دیدگاه

  1. سلام خسته نباشید
    من اینجوری برداشت کردم که اگر (طبق مثال بالا) ما در حلقه while به item مقدار اضافه کنیم مقدار آن اضافه نخواهد شد
    اما این کار در خارج از حلقه while امکان پذیر است..
    درسته؟؟؟ توضیح یه کم مبهم بود

    یاحق

    1. من این توضیح رو خودم ننوشتم و از 2 تا سایت بالا نقل کردم به خاطر همین یکم مبهم شد. خلاصش اینه که وقتی یه متغییر رو در حلقه یا تابع دیگه ای مقدارش رو تغییر می دید ولی تا مقدار تغییر کنه شاید شما یه رویدادی رو از دست بدین استفاده از این کلمه باعث چک شدن مقدار متغییر در هر زمان که متغییر مورد استفاده قرار میگیره میشه

  2. دوست عزیز.
    ممنون از وبسایت بسیار خوب و پر محتواتون
    متغیر های Volatile در کامپایلر Keil بیشتر زمان هایی استفاده میشه که شما دو تا سورس کد داشته باشی و بخوای یک متغیر رو در هر دو سورس کد استفاده کنی.برای همین توی یک سورس اون متغیر رو Volatile و تو سورس کد بعدی که همه مربوط به یک پروژه واحد هستن اون متغیر ور extern تعریف میکنی

    تو کدویژن volatile رو زمانی بهتره استفاده کنین که بخواین یک متغیر عمومی رو توی برنامه سرویس وقفتون مقدار دهی کنین.این حالت بیشتر تو زمان هایی بوجود میاد که تابع مربوط به وقفه شما بعد از تابع main صدا زده بشه و یا تو پروژه هایی که چند سورس دارین.تو این حالت ها بدلیل بهینه کردن کد ، کامپایلر در نظر میگیرد که این متغییر دیگر تغییری نمیکند به همین علت در برنامه اصلی آن را دوباره فراخوانی نمیکند و از رجیستر عمومی خود کمک میگیرد تا کد بهینه تر شود.بهتره همیشه متغیر های عمومی که توی برنامه وقفه عمومیتون استفاده میشن رو از جنس volatile تعریف کنین تا این مشکل بوجود نیاد.البته این مشکل بیشتر تو وقفه های بعد از main بوجود میاد.
    موفق باشید

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

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

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