volatile در C++ چیست؟ - هفت خط کد انجمن پرسش و پاسخ برنامه نویسی

volatile در C++ چیست؟

+3 امتیاز
سلام به دوستان.

کلمه کلیدی volatile برای چه نوع متغیرهایی تعریف میشه و دقیقاً چیه ؟
سوال شده خرداد 28, 1393  بوسیله ی Xavi (امتیاز 627)   24 83 110
دوباره تگ گذاری شد خرداد 28, 1393 بوسیله ی BlueBlade

3 پاسخ

+4 امتیاز
 
بهترین پاسخ

در واقع با افزودن این کلمه در ابتدای تعریف متغیر برای کامپایلر مشخص میشه که این متغیر از thread های دیگر هم دستکاری میشه پس با این حساب کامپایلر متوجه میشه که مقدار این متغیر هر لحظه ممکن تغییر کنه و نبایستی کدی که این متغیر در آن دخیل هست را بهنه کنه.جون اگر بهینه شه ممکن جای متغیر مقدار ثابت قرار بگیره. علت بهینه نشدن هم اینه که بجای ذخیره سازی این متغیر در register آن در حافظه نگهداری می کنه.

به کد زیر دقت کنید.

volatile int sec;
void Delay1() {
sec = 0;
while (sec < 5) {
// hargez be 5 nmirese
}
}

زمانی حلقه while متوقف میشه که شما از یک thread دیگه مقدار sec را بزرگتر مساوی 5 کنید.  حال اگر volatile نبود کامپایلر چون میدید sec =0 میومد حلقه را به صورت بی نهایت اجرا می کرد.

در ضمن volatile بودن به معنای atomic بودن نیست چندین Thread به صورت همزمان هم می تونن متغیر Volatile را دستکاری کنند

پاسخ داده شده خرداد 28, 1393 بوسیله ی مصطفی ساتکی (امتیاز 21,998)   24 34 75
انتخاب شد شهریور 5, 1393 بوسیله ی BlueBlade
+4 امتیاز

volatile کلمه کلیدی برای تعریف متغیر ها هستش وکارش هم اینه که از optimize شدن اون متغیر و حذف توسط کامپایلر جلوگیری میکنه .

مثلا ممکنه  متغیر a رو توی کد زیر کامپایلر غیر ضروری تشخیص بده و برای سرعت بیشتر حذفش کنه

void foo(){
   int a=22;
   //do stuffs without using a
}

ولی اگر volatile تعریف بشه این اتفاق نمیفته

volatile int a=22;

این کد ساده رو فرض کنید :

const int VAR = 5;
int main()
{
     int a= VAR;
}

کد اسمبلی که تولید میشه این هست :

; Listing generated by Microsoft (R) Optimizing Compiler Version 18.00.21005.1 

	TITLE	TEST
	.686P
	.XMM
	include listing.inc
	.model	flat

INCLUDELIB OLDNAMES

END

یعنی قسمت مساوی گذاشتن a و همچنین متغیر const گلوبال کاملا حذف شدن !

ولی اگر volatile استفاده کنیم 

const int VAR = 5;
int main()
{
    volatile int a= VAR;
}

کد تولیدی اسمبلی این میشه :

; Listing generated by Microsoft (R) Optimizing Compiler Version 18.00.21005.1 
    TITLE   test
    .686P
    .XMM
    include listing.inc
    .model  flat
 
INCLUDELIB OLDNAMES
 
EXTRN   @__security_check_cookie@4:PROC
PUBLIC  _main
;   COMDAT _main
_TEXT   SEGMENT
_a$ = -4                     
_main   PROC             
; Line 3
    push    ebp
    mov ebp, esp
    push    ecx
; Line 4
    mov DWORD PTR _a$[ebp], 5 
; Line 5
    xor eax, eax
    mov esp, ebp
    pop ebp
    ret 0
_main   ENDP
_TEXT   ENDS
END

 

داخل کد بالا متغیر a با این که استفاده نشده ولی باز هم حذف نشده و مقدار گرفته.

پاسخ داده شده خرداد 28, 1393 بوسیله ی BlueBlade (امتیاز 15,315)   15 18 89
ویرایش شده شهریور 5, 1393 بوسیله ی BlueBlade
توی سی شارپ که از مدیریت حافطه خودکار استفاده میکنه چطوریه؟
توی #C هم به همین شکله جاهایی استفاده میشه که قراره از یک متغیر داخل چند تا thread همزمان استفاده بشه این جا کامپایلر متغیر رو داخل رم ذخیره می کنه و هر بار که هر کدوم از thread ها بخوان بخوننش جدیدترین مقدارشو از رم می خونن
thread یا نخ که به عملیات یک پروسه میگن دقیقا چی هست؟ یعنی با یک پردازنده مهمولی 1 هسته ای هم میشه کار کرد یا حتما باید 2 هسته به بالا باشه؟ و برناممون چطور تعداد پرازنده هارو بفهمه که نخ هارو موازی روی پردازنده ها اجرا کنه ممنون.
شما هر تعداد thread که بخواهید می تونید داشته باشید (بشرطی که فضای  رم تموم نشه چون هر thread یک فضای stack اختصاصی داره که داخلش اجرای توابع متغیر ها و... رو ذخیره می کنه پیش فرض فکر کنم ۲ مگابایت باشه پس مثلا ۱۰۰ تا thread دویست مگ حافظه میخواد ) . با پردازنده تک هسته ای هم شدنیه این وظیفه سیستم عامله که چجوری thread ها اجرا بشن مثلا سیستم عامل هر thread رو چند میلی ثانیه اجرا می کنه به شکلی که به نظر میرسه برنامه داره بصورت موازی اجرا میشه .
در مورد معنی thread
thread یعنی یکسری دستورالعمل که سیستم عامل بصورت جداگانه زمان بندی و اجرا می کنه .
یعنی اگه با یک سی پی یو 1 هسته ای برناممونو ترید بندی کنیم سرعت اجراش با همون برنامه معمولی در همون سیستم  فرقی میکنه ؟ کار برنامه مثلا پردازش صدا یا تصویره.
نه اگر یک هسته داشته باشه تاثیر زیادی توی سرعت نداره  شاید سرعت کمتر هم بشه .ولی خب حتی با یک هسته هم خیلی وقت ها نیاز میشه به چند تا thread مثلا یک برنامه یکه هم به اینترنت متصله هم gui داره هم میخواد همزمان یک فایل رو بخونه به سه تا thread نیاز پیدا می کنه که مثلا  gui برنامه موقع  رسیدن اطلاعات از اینترنت یا خوندن فایل هنگ نکنه  .البته در مورد پردازش تصویر یا صدا علاوه بر cpu از gpu هم استفاده میشه .
دقیقا , اگه تک سی پی یو باشه سرعت پایین میاد مخصوصا اگه سرعت فرکانس هم بالا نباشه , بعدش یک سری برنامه هم داریم که توی بک گراند اجرا میشن اونم میشه گفت که ترید هست؟
نه هر برنامه در جال اجرا هرکدوم یک process هستن.(برنامه های در حال اجرا در بک گراند هم شاملشون میشه)
  هر process خودش میتونه شامل  یک یا چند تا thread باشه . و فرق اصلیش با thread  اینه که فضای مموری که thread ها استفاده می کنن بینشون به اشتراک گذاشته ولی برای process این طور نیست و هر کدوم فضای مخصوص خودشون رو دارن .
const_cast هم مثل volatile عمل میکنه ؟
نه const_cast برای این استفاده میشه که const بودن متغیر رو حذف کنیم مثلا http://coliru.stacked-crooked.com/a/a0fb7097d0a51c94
volatile کارش متفاوت هستش .
منظورش اینه که با const cast میشه volatile بودن یک متغیر رو هم حذف کرد مثل مثال بالا که const بودن حذف شد .
سوال شما این بود که
"const_cast هم مثل volatile عمل میکنه ؟ "
که معنی خاصی نمیده مثل اینه که بگین آیا const_cast مثل const هست
0 امتیاز
در C++11، از کلمه کلیدی volatile  برای تعیین متغیرهایی استفاده می شود که ممکن است به صورت ناهمزمان توسط رشته دیگری یا توسط یک روال سرویس وقفه اصلاح شوند. متغیرهای فرار در برنامه نویسی سطح پایین استفاده می شوند تا اطمینان حاصل شود که کامپایلر هیچ بهینه سازی را انجام نمی دهد که می تواند بر رفتار صحیح برنامه تأثیر بگذارد.
 
کلمه کلیدی فرار را می توان برای هر نوع متغیری از جمله int، float، double، char و انواع تعریف شده توسط کاربر اعمال کرد. وقتی یک متغیر به عنوان volatile اعلام می شود، به کامپایلر می گوید که مقدار متغیر ممکن است به طور غیرمنتظره ای تغییر کند و کامپایلر نباید هیچ بهینه سازی هایی را انجام دهد که منجر به رفتار نادرست شود.
 
به عنوان مثال، کد زیر را بدون volatile در نظر بگیرید:
int x;
int main() {
  x = 0;
  while (x == 0) {
    // do something
  }
}

 

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

volatile int x;
int main() {
  x = 0;
  while (x == 0) {
    // do something
  }
}

در این حالت، کامپایلر حلقه را بهینه نمی‌کند و مطمئن می‌شود که برنامه هنگ نمی‌کند.

پاسخ داده شده بهمن 11, 1401 بوسیله ی farshid_siyah (امتیاز 1,463)   3 11 16
...