Re[12]: volatile у переменной класса
От: Tom Россия http://www.RSDN.ru
Дата: 18.01.05 12:06
Оценка:
ME>Приведи конкретный пример.

Сырец
// VolatileTest.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"


// Допустим флаг некоего потока (хотя конечно так лучше не делать)
//
int Variable1 = 0;

//
// Некоя переменная для вычислений. Допустим она используеться
// одновременно из нескольких потоков.
//
int Variable2 = 0;

int Thread()
{
    while(Variable1 == 0)
    {
        Variable2 += 123;

        if (++Variable2 > 6134)
        {
            Variable2 -= 534;
            Variable2 *= Variable2;
        }
        else
        {
            Variable2 -= 32;
            Variable2 += Variable2 / 2;
        }

        Sleep(1);
    }

    return 0;
}

void FireFlag()
{
    Variable1 = 1;
}

int _tmain(int argc, _TCHAR* argv[])
{
    //
    // Need to look generated assembler code in the release version
    //
    __asm int 3;

    //
    // Assume another thread here
    //
    Thread();

    //
    // Signal the Flag
    //
    FireFlag();

    return 0;
}


Без волатайла
int Thread()
{
    while(Variable1 == 0)
00401000  mov         eax,dword ptr [Variable1 (4072C0h)] 
00401005  test        eax,eax 
00401007  jne         Thread+53h (401053h) 
00401009  push        esi  
0040100A  mov         esi,dword ptr [__imp__Sleep@4 (405000h)] 
    {
        Variable2 += 123;

        if (++Variable2 > 6134)
00401010  mov         ecx,dword ptr [Variable2 (4072C4h)]  Один раз закешировали и начали использовать уже регистр
00401016  add         ecx,7Ch 
00401019  cmp         ecx,17F6h 
0040101F  jle         Thread+33h (401033h) 
        {
            Variable2 -= 534;
00401021  sub         ecx,216h 
            Variable2 *= Variable2;
00401027  mov         eax,ecx 
00401029  imul        eax,ecx 
0040102C  mov         dword ptr [Variable2 (4072C4h)],eax  Слили в память только тут
        }
        else
00401031  jmp         Thread+45h (401045h) 
        {
            Variable2 -= 32;
00401033  sub         ecx,20h 
            Variable2 += Variable2 / 2;
00401036  mov         eax,ecx 
00401038  cdq              
00401039  sub         eax,edx 
0040103B  sar         eax,1 
0040103D  add         ecx,eax 
0040103F  mov         dword ptr [Variable2 (4072C4h)],ecx  Слили в память только тут
        }

        Sleep(1);
00401045  push        1    
00401047  call        esi  
00401049  mov         eax,dword ptr [Variable1 (4072C0h)] 
0040104E  test        eax,eax 
00401050  je          Thread+10h (401010h) 
00401052  pop         esi  
    }

    return 0;


С волатайлом
int Thread()
{
    while(Variable1 == 0)
00401000  mov         eax,dword ptr [Variable1 (4072C0h)] 
00401005  test        eax,eax 
00401007  jne         Thread+86h (401086h) 
00401009  push        esi  
0040100A  mov         esi,dword ptr [__imp__Sleep@4 (405000h)] 
    {
        Variable2 += 123;
00401010  mov         eax,dword ptr [Variable2 (4072C4h)] 
00401015  add         eax,7Bh 
00401018  mov         dword ptr [Variable2 (4072C4h)],eax

        if (++Variable2 > 6134)
0040101D  mov         ecx,dword ptr [Variable2 (4072C4h)] 
00401023  inc         ecx  
00401024  mov         dword ptr [Variable2 (4072C4h)],ecx
0040102A  cmp         dword ptr [Variable2 (4072C4h)],17F6h
        {
            Variable2 -= 534;
00401034  mov         edx,dword ptr [Variable2 (4072C4h)] 
0040103A  jle         Thread+58h (401058h) 
0040103C  sub         edx,216h 
00401042  mov         dword ptr [Variable2 (4072C4h)],edx 
            Variable2 *= Variable2;
00401048  mov         eax,dword ptr [Variable2 (4072C4h)] 
0040104D  mov         ecx,dword ptr [Variable2 (4072C4h)] 
00401053  imul        eax,ecx 
        }
        else
00401056  jmp         Thread+73h (401073h) 
        {
            Variable2 -= 32;
00401058  sub         edx,20h 
0040105B  mov         dword ptr [Variable2 (4072C4h)],edx 
            Variable2 += Variable2 / 2;
00401061  mov         eax,dword ptr [Variable2 (4072C4h)] 
00401066  mov         ecx,dword ptr [Variable2 (4072C4h)] 
0040106C  cdq              
0040106D  sub         eax,edx 
0040106F  sar         eax,1 
00401071  add         eax,ecx 
        }

        Sleep(1);
00401073  push        1    
00401075  mov         dword ptr [Variable2 (4072C4h)],eax 
0040107A  call        esi  
0040107C  mov         eax,dword ptr [Variable1 (4072C0h)] 
00401081  test        eax,eax 
00401083  je          Thread+10h (401010h) 
00401085  pop         esi  
    }

    return 0;
00401086  xor         eax,eax 
}


Вот и представь, что Thread, испольняется несколькими потоками... Выходит, что потоки узнают о изменениях переменной, только тогда, когда компилятор соизволит слить её в память, а он может этого неделать оочень долго... Почувствуйте разницу
Народная мудрось
всем все никому ничего(с).
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.