Re: Реальный пример использования volatile
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 18.01.05 09:48
Оценка:
Здравствуйте, What, Вы писали:

Но ведь здесь не используются примитивы синхронизации! С моей точки зрения, это как раз опасная практика -- изменять значение в одном потоке без блокирования чтения из другого потока.

Если бы вы использовали синхронизацию доступа к go, то volatile, наверняка, не потребовался бы.

W>Достаточно часто реально используется следующая схема.

W>Есть рабочий поток, который в цикле выполняет интенсивные вычисления. Рабочий поток периодически опрашивает состояние глобальной переменной и, если всё ок, продолжает работать, иначе останавливается. Если пользователь решил отменить действие, GUI-поток меняет значение этой переменной.
W>
W>#include <iostream>
W>#include <process.h>
W>#include <windows.h>

W>/*volatile*/ bool go = true;
W>const unsigned int MaxIter = 1000000000;

W>// Эта процедура выполняет интенсивный вычисления.
W>unsigned int __stdcall Calc(void *)
W>{
W>    double sum = 0.0;
W>    for (unsigned int i = MaxIter; (i != 0) && go; --i)
W>        sum += 1. / i;
W>    std::cout << "sum = " << sum << std::endl;
W>    return 0;
W>};

W>int main()
W>{
W>    unsigned int id;
W>    HANDLE h = reinterpret_cast<HANDLE>(_beginthreadex(NULL, 0,  &Calc, NULL, 0, &id));
W>    // Пользователь подумал 20 миллисекунд
W>    ::Sleep(20);
W>    // .. и решил отменить вычисления
W>    go = false;
W>    ::WaitForSingleObject(h, INFINITE);
W>    ::CloseHandle(h);
W>    return 0;
W>}
W>


W>Так вот, когда volatile закомментирован, то рабочий поток не останавливается программа выводит:

W>

W>21.3005


W>А когда volatile есть, поток останавливается и программа выводит:

W>

W>0.00287083


W>Компилятор VC 7.1. Командная строка:

W>
W>/O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /FD /EHsc
W>/MD /GS /Fo"Release/" /Fd"Release/vc70.pdb" /W3 /nologo /c /Wp64 /Zi /TP
W>
... << RSDN@Home 1.1.4 beta 3 rev. 185>>


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[7]: volatile у переменной класса
От: MaximE Великобритания  
Дата: 18.01.05 09:53
Оценка:
Tom wrote:

> ME>Т.е. ты взял и не читая ляпнул?

> Не горячись
>
> ME>http://www.rsdn.ru/forum/?mid=989456
Автор: MaximE
Дата: 16.01.05

> ME>http://www.rsdn.ru/forum/?mid=988910
Автор: MaximE
Дата: 15.01.05

> ME>http://www.rsdn.ru/forum/?mid=991653
Автор: MaximE
Дата: 17.01.05

>
> Знавчицца так: Берёшь простенькую программу с обьявленной глобальной volatile и нет переменной. Компилируешь в релизе разными компиляторами. Я проверял на: VC6, VC7.1, gcc 2.95, gcc 3.2, Sun One Studio 5. И смотришь разницу

Разницу в чем?

Еще раз, почитай по указанным ссылкам.

> Ещё раз говорю, что переменная, использующаяся в разных потоках, кроме того, что должна быть защищена приметивами синзхронизации обязана быть volatile.


Ok, тогда запость, пожалуйста, Александру Терехову ответ на его сообщение http://groups-beta.google.com/group/comp.std.c/msg/ae49dc7a96c625f5 в ньюсгруппу и копию на его e-mail, что ерунду он написал что volatile не нужен для синхронизации в multithreading, а мы тут все вместе почитаем его ответ.

--
Maxim Yegorushkin
Posted via RSDN NNTP Server 1.9
Re[5]: [2]: : volatile: а можно примеры?
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 18.01.05 09:59
Оценка: 20 (3) +1
Здравствуйте, Шахтер, Вы писали:

Ш>Они уже приведены.


То, что я видел выше нельзя назвать примерами реальных проектов. Это небольшие тестовые программки, которые дополнены комментариями типа "вот когда-нибудь, когда придут крутые-крутые компиляторы, которые увидят, как работают WaitForSingleObject/pthread_mutex_wait, вот тогда...". И еще говорят, что компилятор справедливо опасается оптимизировать доступ к переменным, если перед этим были сделалы какие-то внешние вызовы.

Как мне кажется, довольно характерный пример псевдокода по работе о общими данными в многопоточных приложениях выглядит так:
// Кто-то, что-то готовит.
lock();
...
flag = ready;
unlock();

// Кто-то, что-то ожидает.
while( true )
    lock();
    if( ready != flag )
        unlock();
    else
        ...
        ready = not_ready;
        unlock();

Причем как раз доступ к общим данным (в данном случае, flag) производиться рядышком с использованием синхронизирующих примитивов.

Из того, что я прочитал, я сделал вывод, что компилятор не будет оптимизировать доступ к общим данным, если рядом есть вызов синхронизирующего примитива (просто потому, что компилятор будет считать этот вызов вызовом с побочными эфектами). Компиляторы не делают такой оптимизации сейчас. И я сомневаюсь, что они будут делать ее в будущем. Хотя бы из-за соображений совместимости.

Поэтому пока я не считаю нужным делать рефакторинг своего кода и вставлять volatile туда, где его не было. И я не увидел пока реальных примеров из жизни, которые заставили бы меня это сделать. А было бы полезно увидеть (не только мне), если такие примеры имели место быть.
... << RSDN@Home 1.1.4 beta 3 rev. 185>>


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[8]: volatile у переменной класса
От: Tom Россия http://www.RSDN.ru
Дата: 18.01.05 10:26
Оценка:
ME>Разницу в чем?
Разницу в генерируемом компилятором коде.

>> Ещё раз говорю, что переменная, использующаяся в разных потоках, кроме того, что должна быть защищена приметивами синзхронизации обязана быть volatile.


ME>Ok, тогда запость, пожалуйста, Александру Терехову ответ на его сообщение http://groups-beta.google.com/group/comp.std.c/msg/ae49dc7a96c625f5 в ньюсгруппу и копию на его e-mail, что ерунду он написал что volatile не нужен для синхронизации в multithreading, а мы тут все вместе почитаем его ответ.

Ты путаешь понятия (или подменяешь). Мы говорим не о том, что volatile необходим только в multithreaded приложениях, а о том что он необходим при использовании переменной несколькими потоками (процессами), но это не отменяет его применимости в других ситуациях.
Народная мудрось
всем все никому ничего(с).
Re[8]: [2]: : volatile: а можно примеры?
От: AndrewJD США  
Дата: 18.01.05 10:26
Оценка: +2
Здравствуйте, MaximE, Вы писали:

>> ME>Мой поинт был в том (если этого до сих пор непонятно уважаемому Шахтеру), что какой бы семантикой не обладал volatile, ее просто не достаточно для multithreading, и поэтому volatile бесполезен для multithreading.

>>
>> не вдаваясь в технические подробности, из "недостаточно" никак не может следовать "и поэтому ... бесполезен"

ME>На этом основании ты хочешь объявить все написанное здесь ересью и провозгласить, что volatile необходим и достаточен для обеспечиния синхронизации при multithreading?


volatile — необходимое (в ряде случаев), но не достаточное условие
"For every complex problem, there is a solution that is simple, neat,
and wrong."
Re[9]: volatile у переменной класса
От: MaximE Великобритания  
Дата: 18.01.05 10:31
Оценка:
Tom wrote:

[]

Мы говорим не о том, что volatile необходим только в multithreaded приложениях, а о том что он необходим при использовании переменной несколькими потоками (процессами)...

Это здесь уже обсудили. Он ни достаточен, ни необходим. Вся информация тебе доступна, читай.

--
Maxim Yegorushkin
Posted via RSDN NNTP Server 1.9
Re[9]: [2]: : volatile: а можно примеры?
От: MaximE Великобритания  
Дата: 18.01.05 10:35
Оценка:
AndrewJD wrote:

> Здравствуйте, MaximE, Вы писали:

>
>>> ME>Мой поинт был в том (если этого до сих пор непонятно уважаемому Шахтеру), что какой бы семантикой не обладал volatile, ее просто не достаточно для multithreading, и поэтому volatile бесполезен для multithreading.
>>>
>>> не вдаваясь в технические подробности, из "недостаточно" никак не может следовать "и поэтому ... бесполезен"
>
> ME>На этом основании ты хочешь объявить все написанное здесь ересью и провозгласить, что volatile необходим и достаточен для обеспечиния синхронизации при multithreading?
>
> volatile — необходимое (в ряде случаев), но не достаточное условие

http://groups-beta.google.com/group/comp.programming.threads/msg/21878c22d7775997

Memory barriers must be applied where necessary on many architectures, and
there is no standard or portable way to generate them. There is no excuse for a
compiler to require both volatile AND memory barriers, because there's no
excuse for a compiler to reorder memory access around its own memory barrier
construct. (Usually either a compiler builtin such as Compaq C/C++ "__MB()" or
an asm("mb") "pseudocall".) The standard and portable way to ensure memory
consistency is to rely on the POSIX memory model, which is based solely on
specific POSIX API calls rather than expensive and inappropriately defined
language keywords or nonportable hardware instructions. A system or compiler
that does not provide the proper memory model (without volatile) with proper
use of the portable POSIX API calls does not conform to POSIX, and cannot be
considered for serious threading work. Volatile is irrelevant.


Entirely aside from the language issues, my point was simply that "volatile",
and especially its association with threaded programming, has been an extremely
confusing issue for many people. Simply using them together is going to cause
even more confusion. The illusory promise of volatile will lead novices into
trouble.


In contradiction to your absurd statement that "writing multithread programs
becomes impossible" without volatile, the intended C and C++ semantics
associated with volatile are neither useful nor sufficient for threaded code.

And it is WITH volatile, not without, that "the compiler wastes vast
optimization opportunities", especially as the expense of meeting the volatile
"contract" is of no benefit to threaded code.


--
Maxim Yegorushkin
Posted via RSDN NNTP Server 1.9
Re[10]: volatile у переменной класса
От: Tom Россия http://www.RSDN.ru
Дата: 18.01.05 10:46
Оценка: :)
ME>Это здесь уже обсудили. Он ни достаточен, ни необходим. Вся информация тебе доступна, читай.
То, что он нидостаточен — это естественно, Но он необходим. Советую не ляпать на клавиатуре, а попробовать самому
Народная мудрось
всем все никому ничего(с).
Re[11]: volatile у переменной класса
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 18.01.05 10:59
Оценка:
Здравствуйте, Tom, Вы писали:

Tom>То, что он нидостаточен — это естественно, Но он необходим. Советую не ляпать на клавиатуре, а попробовать самому


Приведите пример, пожалуйста.
... << RSDN@Home 1.1.4 beta 3 rev. 185>>


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[11]: volatile у переменной класса
От: MaximE Великобритания  
Дата: 18.01.05 11:03
Оценка:
Tom wrote:

> ME>Это здесь уже обсудили. Он ни достаточен, ни необходим. Вся информация тебе доступна, читай.

> То, что он нидостаточен — это естественно, Но он необходим.

Приведи конкретный пример.

--
Maxim Yegorushkin
Posted via RSDN NNTP Server 1.9
Re[2]: Реальный пример использования volatile
От: What Беларусь  
Дата: 18.01.05 11:28
Оценка: 1 (1)
Здравствуйте, eao197, Вы писали:

E>Здравствуйте, What, Вы писали:


E>Но ведь здесь не используются примитивы синхронизации! С моей точки зрения, это как раз опасная практика -- изменять значение в одном потоке без блокирования чтения из другого потока.


А зачем здесь синхронизация? Один поток пишет значение переменной, другой читает. Главное, чтобы значение было записано атомарно. Это в данном случае для x86 гарантируется.
С другой стороны, а если бы рабочих потоков было, скажем, 4 вместо 1. И все читали бы одну и ту же переменную. Тогда использование синхронизации могло бы привести к ненужным потерям производительности.

E>Если бы вы использовали синхронизацию доступа к go, то volatile, наверняка, не потребовался бы.

Наверняка, да, не потребовался бы.
... << RSDN@Home 1.1.4 beta 3 rev. 185>>
Re[5]: volatile у переменной класса
От: What Беларусь  
Дата: 18.01.05 11:48
Оценка:
Здравствуйте, MaximE, Вы писали:

ME>Еще раз — volatile абсолютно бесполезен для multithreading.

На мой взгляд, это слишком категорично. Volatile может быть полезен для multithreading.

Вы приводили ссылки:
You do NOT need volatile for threaded programming. You do need it when you share
data between "main code" and signal handlers, or when sharing hardware registers
with a device. In certain restricted situations, it MIGHT help when sharing
unsynchronized data between threads
(but don't count on it -- the semantics of
"volatile" are too fuzzy).
... << RSDN@Home 1.1.4 beta 3 rev. 185>>
Re[3]: Реальный пример использования volatile
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 18.01.05 11:56
Оценка: 9 (1)
Здравствуйте, What, Вы писали:

W>А зачем здесь синхронизация? Один поток пишет значение переменной, другой читает. Главное, чтобы значение было записано атомарно. Это в данном случае для x86 гарантируется.


Боюсь, что именно из-за таких предположений весь сыр бор вокруг volatile и начался. Я считаю, что есть принципиальные вещи: выделеную память нужно освобождать, открытые файлы закрывать, после входа в критическую секцию нужно выйти оттуда, ..., когда одна нить читает то, что другая может переписать, то это нужно синхронизировать. Это вопрос принципа (с моей точки зрения). И если ему следовать, то:
— мы не зависим от volatile или не volatile;
— мы не зависим от аппаратной платформы (могут быть какие-нибудь специализированные процессоры, на которых извлечение одного байта из памяти может не быть атомарной операцией, а требовать дополнительных арифметических операций/сдвигов);
— мы не зависим от типа данных. Сейчас у нас переменная go -- это bool. Завтра -- это long int, в котором указано, сколько итераций нам еще разрешают сделать. После завтра -- структура, в которой описывается, при каких условиях нужно выходить, а при каких условиях еще можно провести пару-тройку итераций.
А все из-за того, что изначально мы защитились синхронизацией. И не надеялись на особенности конкретной платформы и конткретного компилятора.

W>С другой стороны, а если бы рабочих потоков было, скажем, 4 вместо 1. И все читали бы одну и ту же переменную. Тогда использование синхронизации могло бы привести к ненужным потерям производительности.

За безопасность в многопоточности нужно платить. Некоторые из-за безопасности на более медленные языки программирования переходят Из-за того, что лишний раз delete вызвать лень

E>>Если бы вы использовали синхронизацию доступа к go, то volatile, наверняка, не потребовался бы.

W>Наверняка, да, не потребовался бы.

От тож!
... << RSDN@Home 1.1.4 beta 3 rev. 185>>


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
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, испольняется несколькими потоками... Выходит, что потоки узнают о изменениях переменной, только тогда, когда компилятор соизволит слить её в память, а он может этого неделать оочень долго... Почувствуйте разницу
Народная мудрось
всем все никому ничего(с).
Re[13]: volatile у переменной класса
От: MaximE Великобритания  
Дата: 18.01.05 12:17
Оценка: +1
Tom wrote:

> ME>Приведи конкретный пример.

>
> Сырец

[]

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


Этот код — некорректный многопоточный код, так как он не применяет синхронизацию для доступа к переменной.

Это уже обсуждалось в ветке.

--
Maxim Yegorushkin
Posted via RSDN NNTP Server 1.9
Re: volatile у переменной класса
От: sc Россия  
Дата: 18.01.05 12:18
Оценка:
Здравствуйте, Vet, Вы писали:

Vet>В объекте класса есть переменная, которая используется двумя потоками.
Vet>Один из потоков иногда меняет ее значение.
Vet>Есть ли необходимость в этом случае делать переменную как volatile.

Есть, например простой пример:
volatile int var1 = 1; //ее используют два потока
...
int var2 = var1 = 2;
var2 = var1;

Видно, что в результате var2 = 2, но это если не было переключения между потоками ровно после первого присваивания. А если было, то тогда var2 будет иметь новое значение var1. А если не использовать volatile, то второе присваивание будет удалено в результате оптимизации.
Пример примитивный конечно, в реальной жизни все может быть намного сложнее, и особенно поиск ошибки такого типа.
Re[6]: volatile у переменной класса
От: MaximE Великобритания  
Дата: 18.01.05 12:25
Оценка:
Здравствуйте, What, Вы писали:

W>Здравствуйте, MaximE, Вы писали:


ME>>Еще раз — volatile абсолютно бесполезен для multithreading.

W>На мой взгляд, это слишком категорично. Volatile может быть полезен для multithreading.

W>Вы приводили ссылки:

W>You do NOT need volatile for threaded programming. You do need it when you share
W>data between "main code" and signal handlers, or when sharing hardware registers
W>with a device. In certain restricted situations, it MIGHT help when sharing
W>unsynchronized data between threads
(but don't count on it -- the semantics of
W>"volatile" are too fuzzy).

Ok, ты работаешь над проектом. Менеджер спрашивает тебя, готов ли ты поставить свою зарплату, что твой многопоточный кусок кода, в котором ты не используешь ф-ций синхронизации, а полагаешься на "fuzzy" семантику volatile, заработает на не Intel SMP системе? Что ты ему ответишь?
Re[4]: Реальный пример использования volatile
От: What Беларусь  
Дата: 18.01.05 12:30
Оценка:
Здравствуйте, eao197, Вы писали:

W>>А зачем здесь синхронизация? Один поток пишет значение переменной, другой читает. Главное, чтобы значение было записано атомарно. Это в данном случае для x86 гарантируется.


E>Боюсь, что именно из-за таких предположений весь сыр бор вокруг volatile и начался. Я считаю, что есть принципиальные вещи: выделеную память нужно освобождать, открытые файлы закрывать, после входа в критическую секцию нужно выйти оттуда, ..., когда одна нить читает то, что другая может переписать, то это нужно синхронизировать. Это вопрос принципа (с моей точки зрения). И если ему следовать, то:

E>- мы не зависим от volatile или не volatile;
E>- мы не зависим от аппаратной платформы (могут быть какие-нибудь специализированные процессоры, на которых извлечение одного байта из памяти может не быть атомарной операцией, а требовать дополнительных арифметических операций/сдвигов);
E>- мы не зависим от типа данных. Сейчас у нас переменная go -- это bool. Завтра -- это long int, в котором указано, сколько итераций нам еще разрешают сделать. После завтра -- структура, в которой описывается, при каких условиях нужно выходить, а при каких условиях еще можно провести пару-тройку итераций.
E>А все из-за того, что изначально мы защитились синхронизацией. И не надеялись на особенности конкретной платформы и конткретного компилятора.
Для того, чтобы не зависеть от платформы, нужно разделять платформенно-зависимый и платформенно-независимый код. А вот платформенно-зависимые примитивы, например, средства синхронизации могут быть реализованы отдельно под некоторые платформы максимально эффективным способом. И если под x86 работа с 32-битными числами атомарна, то в платформенно-зависимых частях кода нужно это использовать.

W>>С другой стороны, а если бы рабочих потоков было, скажем, 4 вместо 1. И все читали бы одну и ту же переменную. Тогда использование синхронизации могло бы привести к ненужным потерям производительности.

E>За безопасность в многопоточности нужно платить. Некоторые из-за безопасности на более медленные языки программирования переходят Из-за того, что лишний раз delete вызвать лень
Да, но зачем платить, когда это не нужно? Например, критические секции, если не надо останавливать поток, обходятся без перехода в режим ядра. Другой пример — паттерн double-checked locking, при реализации которого, кстати, может понадобиться volatile.
... << RSDN@Home 1.1.4 beta 3 rev. 185>>
Re[5]: Реальный пример использования volatile
От: MaximE Великобритания  
Дата: 18.01.05 12:38
Оценка: 6 (1)
What wrote:

... Другой пример — паттерн double-checked locking, при реализации которого, кстати, может понадобиться volatile.

[q]
http://groups-beta.google.com/group/comp.lang.c++.moderated/browse_frm/thread/811a3ae4eea2d481/

The problem exists, because the C++ standard allows reordering of C++ statements,
as long as the observable behaviour stays the same — with the bad side
effect that the "observable behavior" in C++ is not multi-threading
aware and this finally leads to Scott's conclusion: "There is no
portable way to implement DCLP in C++".

[/c]

--
Maxim Yegorushkin
Posted via RSDN NNTP Server 1.9
Re[14]: volatile у переменной класса
От: Tom Россия http://www.RSDN.ru
Дата: 18.01.05 12:51
Оценка: :)
ME>Этот код — некорректный многопоточный код, так как он не применяет синхронизацию для доступа к переменной.

А ты думаешь компилятор перестанет оптимизировать, если появиться синхронизация?
Народная мудрось
всем все никому ничего(с).
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.