Re[15]: volatile у переменной класса
От: Шахтер Интернет  
Дата: 16.01.05 00:59
Оценка: :)
Здравствуйте, MaximE, Вы писали:

ME>emusic wrote:


ME>[]


>> Обосновать это свое утверждение чем-либо, кроме собственной смутной интуиции, можешь? Я тебе привел пример программы, которая без volatile корректно работать не будет. Найди в этом примере ошибку, либо приведи доказательство того, что любая многопоточная программа обязана корректно работать без volatile. Пока бОльшую часть приведенных тебе аргументов ты тихо опускаешь, повторяя в ответ одни и те же измышления.


ME>Весь мир давно заездил эту тему до дыр, только до rsdn прогрессивная мысль никак не доберется (.


ME>--

ME>Maxim Yegorushkin

В данном случае ты очень крупно заблуждаешься. Насчет заезженной темы -- ключевое слово volatile появилось очень давно и имеет вполне определённую семантику использования, которая поддерживается C/C++ компиляторами. Если кто-то плохо знаком с вопросом и фантазирует на тему в том или другом форуме, то это личная беда этих людей. Вместо того, чтобы упираться, изучи лучше листинги, которвые я тебе привел -- они очень красноречивы.
... << RSDN@Home 1.1.0 stable >>
В XXI век с CCore.
Копай Нео, копай -- летать научишься. © Matrix. Парадоксы
Re[15]: volatile у переменной класса
От: emusic Франция https://software.muzychenko.net/ru
Дата: 16.01.05 04:57
Оценка: -1
Здравствуйте, MaximE, Вы писали:

ME>emusic wrote:


>> Указание ключа /Oa сообщает компилятору, что в программе подобные совмещения исключены.


ME>... но на самом деле они у тебя в проге есть и ты полагаешься на результат этого альясинга. Ты сообщил компилятору неверную информацию — all bets are off.


Чтоб ты не измыслил очередной ерунды — приведу перечень условий отсутствия aliasing'а из MSDN. Будь любезен, укажи, какие места моего примера какие из этих пунктов нарушают:

If you use /Oa or /Ow, you must follow these rules. The following rules apply for any variable not declared as volatile:

No pointer can reference a variable that is used directly (a variable is referenced if it is on either side of an assignment or if a function uses it in an argument).
No variable can be used directly if a pointer to the variable is being used.
No variable can be used directly if its address is taken within a function.
No pointer can be used to access a memory location if another pointer modifies the same memory location.


Разумеется, ты будешь ссылаться на четвертый пункт, ибо переменной в "чистом" виде в программе может и не быть Однако с чего ты взял, что в программе одновременно будет существовать два указателя на одну и ту же область? Напомню, ты сам дважды подчеркивал, что многопоточность в модели C++ отсутствует. И "в пространстве" (в каждом отдельном потоке) может существовать не более одного указателя на каждую область памяти. Это и есть отсутствие aliasing'а, о чем сообщается компилятору.

А то, что подобное совмещение указателей существует "во времени" — это уже совершенно другой вопрос. В конце концов, эта область памяти может модифицироваться непосредственно аппаратурой, у которой нет никаких "указателей", а только провода
... << RSDN@Home 1.1.4 beta 3 rev. 185>>
Re[15]: volatile у переменной класса
От: emusic Франция https://software.muzychenko.net/ru
Дата: 16.01.05 05:34
Оценка: :)
Здравствуйте, MaximE, Вы писали:

ME>Весь мир давно заездил эту тему до дыр, только до rsdn прогрессивная мысль никак не доберется (.


Слушай, а может, у тебя с английским плохо? В этих дискуссиях никто америки не открыл, и большинство компетентных мнений сходится, конечно же, к тому, что ни volatile, ни memory barriers сами по себе проблемы не решают, и в общем случае решают ее лишь в совокупности. А ты с самого начала уперся в простейшие частные случаи вроде InterlockedXXX, и необязательность volatile для таких переменных смело распространил на все остальное, опираясь на наиболее одиозные утверждения в приведенном списке ссылок Конечно, если читать из этого списка только то, где высказывается близкая тебе точка зрения, в подобное заблуждение впасть нетрудно
... << RSDN@Home 1.1.4 beta 3 rev. 185>>
Re[16]: volatile у переменной класса
От: MaximE Великобритания  
Дата: 16.01.05 10:00
Оценка: 19 (3)
c-smile wrote:

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

>
> ME>Весь мир давно заездил эту тему до дыр, только до rsdn прогрессивная мысль никак не доберется (.
>
> Макс, это уже не смешно.
> Или давай технические спеки или ссылки на докуметнацию компиляторов.
> Короче что-нибудь, но не ссылки на threads в дискуссиях ведущихся анонимными авторами.

В большинстве случаев авторы постингов имеют достаточные известные имена. Анонимов там почти нет.

> "Весь мир давно заездил эту тему" ты имеешь ввиду себя и пару тройку "просвященных"?

> Примерно 25% этого мира посещяет RSDN на котором мы видим "луч света в темном царстве" в твоем лице.

Я так не думаю.

> Чего ты уперся? volatile is a C++ keyword. Period.


Это несет ровно такой же смысл, как сказать: "Земля — это планета. Точка."




Мы обсуждаем здесь volatile и multithreading. С этим все согласны?

Я приводил цитаты из док-ции Intel, где они явно рекоммендуют использовать синхронизацию для доступа к shared data. Этого было не достаточно?

Мнение Alexander Terekhov'а (кроме него и Butenhof'a лучшие специалисты по threads мне неизвестны).

http://groups-beta.google.com/group/comp.std.c/msg/ae49dc7a96c625f5

There are (depending on how one breaks these things down) at least three
independent issues here:


1. Atomic access granularity
2. Read/write ordering
3. Memory coherency


This discussion has been trying to address the three as if they were the
same. They're not even connected. (Or, at best, only very loosely connected.)


Most modern machines (yes, I should probably use quotes again) are designed
for fast and efficient multiprocessing. The memory interconnect is the big
bottleneck, and a lot of work has gone into streamlining the memory access
and cache protocols. Memory accesses are usually made in "chunks" not
necessarily related to the size of the data type. In general, a machine has a
few "memory access types", very likely a smaller set than the set of
instruction set types. Usually, only "memory access types" are atomic. On an
Alpha EV4 and EV5, for example, the memory access types are 32-bit "words"
and 64-bit "longwords". Smaller accesses require loading and masking a word
or longword. While some machines might choose to hide the distinction between
"memory types" and "instruction types", Alpha doesn't. To read a byte, you
must load the enclosing word/longword, (I'll use "word" for convenience from
now on), and use special instructions to mask/shift into the desired
position.


That's all fine, except when you get into concurrently executing entities
(threads, or processes using shared memory), and one tries to STORE into the
non-atomic field. To store such a field, you fetch the current word, shift &
mask (field insert) your new data, and then write the word back. If another
entity is simultaneously setting a different field in the same word, only ONE
of the two will supply a new value for the entire word, including the other
thread's field. Worse, a non-atomic field (e.g., a 16-bit short rather than a
byte) might be split between two words. If it does, you can get into trouble
even reading, because you have to read both words and combine them to create
the short value you want. Some other thread might have changed one of the
words between your two reads. That's "word tearing", and it means you've
gotten the wrong data. Of course word tearing can happen on writes, too, in
addition to the normal field access problems. Messy!


Attempting to share information between concurrently executing instruction
streams (that may be on separate processors) also requires read/write
ordering. That is, if you set a flag to signal some change in state (e.g.,
adding an item to a queue), you must be able to know that seeing the change
in the flag means you can see the new queue item. Modern SMP memory systems
frequently allow reordering of operations in the CPU to memory controller
pipeline, for all sorts of reasons (including cache synchronization issues,
speculative execution, etc.) So you may queue an item and then set a flag (or
fill in the fields of a structure and then queue it), but have the data
become visible to another processor in a different order. Unless you're
communicating between concurrently executing entities, reordering doesn't
affect you -- so it's a great performance tradeoff. But it means that when
you require ordering, you need to do something extra. One common way to force
ordering is a "memory barrier" instruction. On Alpha, for example, MB
prevents memory operation reordering across the instruction. (One could
consider a stream of memory requests in a pipe between the CPU and memory,
which can be arbitrarily reordered for implementation convenience; but the
reordering agent can't move anything past an "MB token".)


And then we've got memory coherency. A "write-through" cache may invalidate
other caches, and update main memory. But a "write-back" cache may not write
into main memory for some time. Even if other caches are invalidated, the
processors won't see the new value until it's written. That's OK, though, as
long as both processors make proper use of memory barriers. The writer puts a
memory barrier between writing the data and writing the flag (or pointer),
and the reader puts a memory barrier between reading the flag/pointer and
reading the data. Now, whenever the flag/pointer appears in memory, you know
that the data to which it points is valid -- because you can't have read it
before the flag, and the writer can't have written it after the flag.


For more information without getting too deep into processor implementation
details, see the section "Memory visibility between threads" in my book
(Programming with POSIX Threads, web link in my .sig). Curt Schimmel's
UNIX Systems for Modern Architectures (Addison-Wesley) has a section called
"Other Memory Models" that describes the SPARC architecture's "Partial Store
Ordering" (loose read/write ordering with memory barriers), though it doesn't
address word tearing.

...

The whole idea of RISC is *exactly* to make software more complex. That is, by
simplifying the hardware, hardware designers can produce more stable designs that
can be produced more quickly and with more advanced technology to result in faster
hardware. The cost of this is more complicated software. Most of the complexity is
hidden by the compiler -- but you can't necessarily hide everything. Remember that
POSIX took advantage of some loopholes in the ANSI C specification around external
calls to proclaim that you can do threaded programming in C without requiring
expensive and awkward hacks like "volatile".
Still, the interpretation of ANSI C
semantics is stretched to the limit. The situation would be far better if a future
version of ANSI C (and C++) *did* explicitly recognize the requirements of threaded
programming.

...
> However, I really believe that dataA and dataB should both be declared as
> "volatile" to prevent the compiler from being too aggressive on it's
> optimization. The mutex still doesn't guarantee that the compiler hasn't
> cached the data in an internal register across a function call. My memory
> isn't perfect, but I do think this bit me on IRIX.


The existence of the mutex doesn't require this, but the semantics of POSIX and
ANSI C do require it. Remember that you lock a mutex by calling a function, passing
an address. While an extraordinarily aggressive C compiler with a global analyzer
might be able to determine reliably that there's no way that call could access the
data you're trying to protect, such a compiler is unlikely -- and, if it existed,
it would simply violate POSIX 1003.1-1996, failing to support threads.


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). If you need volatile to share data, protected by POSIX
synchronization objects, between threads, then your implementation is busted.


...

> If you stick to a "natural machine word" that is declared as "volatile",
> you do not absolutely need a mutex (in fact I've done it). Of course, there are
> only certain cases where this works and shouldn't be done unless you really know
> your hardware architecture and what you're doing! If you have a machine with a
> lot of processors, unnecessarily locking mutexes can really kill parallelism.


> I'll give one example where this might be used:



> volatile int stop_flag = 0; /* assuming an int is atomic */


> thread_1
> {
> /* bunch of code */


> if some condition exists such that we wish to stop thread_2


> stop_flag = 1;


> /* more code — or not */
> }


> thread_2
> {
> while(1)
> {
> /* check if thread should stop */
> if (stop_flag)
> break;


> /* do whatever is going on in this loop */
> }
> }


> Of course, this assumes the hardware has some sort of cache coherency
> mechanism. But I don't believe POSIX mutex's or memory barriers (as
> defined for the DEC alpha) have any impact on cache coherency.


If a machine has a cache, and has no mechanism for cache coherency, then it can't
work as a multiprocessor.



> The example is simplistic, but it should work on a vast majority of
> systems. In fact the stop_flag could just as easily be a counter
> of some sort as long as only one thread is modifying the counter...


In some cases, yes, you can do this. But, especially with your "stop_flag",
remember that, if you fail to use a mutex (or other POSIX-guaranteed memory
coherence operation), a thread seeing stop_flag set CANNOT assume anything about
other program state. Nor can you ensure that any thread will see the changed value
of stop_flag in any particular bounded time -- because you've done nothing to
ensure memory ordering, or coherency.


And remember very carefully that bit about "as long as only one thread is
modifying". You cannot assume that "volatile" will ever help you if two threads
might modify the counter at the same time. On a RISC machine, "modify" still means
load, modify, and store, and that's not atomic. You need special instructions to
protect atomicity across that sequence (e.g., load-lock/store-conditional, or
compare-and-swap).


Am I trying to scare you? Yeah, sure, why not? If you really feel the need to do
something like this, do yourself (and your project) the courtesy of being EXTREMELY
frightened about it. Document it in extreme and deadly detail, and write that
documentation as if you were competing with Stephen King for "best horror story of
the year". I mean to the point that if someone takes over the project from you, and
doesn't COMPLETELY understand the implications, they'll be so terrified of the risk
that they'll rip out your optimizations and use real synchronization. Because this
is just too dangerous to use without full understanding.



There are ways to ensure memory ordering and coherency without using any POSIX
synchronization mechanisms, on any machine that's capable of supporting POSIX
semantics. It's just that you need to be really, really careful, and you need to be
aware that you're writing extremely machine-specific (and therefore inherently
non-portable) code. Some of this is "more portable" than others, but even the
"fairly portable" variants (like your stop_flag) are subject to a wide range of
risks. You need to be aware of them, and willing to accept them. Those who aren't
willing to accept those risks, or don't feel inclined to study and fully understand
the implications of each new platform to which they might wish to port, should
stick with mutexes.


http://groups-beta.google.com/group/comp.lang.c++/browse_frm/thread/82ea6195d505250c/ba4fc712e25a904b?q=volatile+nor+sufficient&amp;_done=%2Fgroups%3Fie%3Dutf-8%26oe%3Dutf-8%26q%3Dvolatile+nor+sufficient%26qt_s%3DSearch+Groups%26&amp;_doneTitle=Back+to+Search&amp;&amp;d#ba4fc712e25a904b

In fact, though you've said you weren't intending to advocate direct access to
any "volatile" variable without applying synchronization and casting away
"volatile", your first Gadget::Wait example does precisely that, and is wildly
incorrect and dangerously misleading. Compiler volatile semantics are not
sufficient when sharing flag_ between threads, because the hardware, as well as
the compiler, may reorder memory accesses arbitrarily, even with volatile. (Nor
would a compiler implementation that issued memory barriers at each sequence
point for volatile variables be sufficient, unless ALL data was volatile, which
is impractical and unreasonably expansive.)


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: volatile: а можно примеры?
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 17.01.05 09:53
Оценка: 1 (1) :)
Добрый день всем.

С большим интересом прочитал развернувшуюся здесь дискуссию. Эта тема меня очень заинтересовала. Дело в том, что я использую многопоточность давно, еще года с 1996, под разными ОС (Win32, OS/2, Linux, FreeBSD, HP NonStop). Но про взаимосвязь между volatile и многопоточностью узнал впервые в этой ветке. Действительно, меньше знаешь -- крепче спишь.

До сих пор программировал без volatile. В основном из-за того, что в далеких 90-х еще не все компиляторы поддерживали такие ключевые слова, как volatile, вот и привык его не использовать (т.к. драйверов на C++ на писал). Написанный мной код, к счастью, работал. Но, по стечению обстоятельств, только на однопроцессорных машинах. Был только один случай, когда одна из систем была установлена на двухпроцессорной машине под Win2K. И как раз там наблюдались странные сбои, которые прекращались после перекомпиляции проекта любым компилятором, отличным от VC6.0sp5 (Borland C++, MinGW, VC7.0). Тогда причину сбоев установить не удалось, т.к. после перехода на VC7.0, а затем VC7.1, сбоев не было.

В связи с этим у меня вопрос: можно ли услышать/увидеть реальные примеры того, как в многопоточных приложениях обнаруживались проблемы из-за того, что не использовалось volatile? Именно реальные, хорошо бы с примерами, хотя бы псевдокода. И не драйверов или софта для работы с железом, а "прикладного" кода.

Просто у меня сложилось такое мнение, что сейчас что с volatile, что без, если используешь штатные средства синхронизации (будь то WinAPI или POSIX), то можно быть спокойным. Более того, разработчики компиляторов не могут не учитывать того факта, что в мире немало программистов (я из их числа), которые не озаботились применением volatile в многопоточном приложении. И если выйдет новая версия компилятора, для которого применение volatile критически важно, то все эти программисты столкнутся с огромным объемом неработоспособного кода. Поэтому можно ожидать, что и в новых компиляторах многопоточные приложения без volatile останутся работоспособными. Но это мое впечатление.

Заранее спасибо.


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[2]: : volatile: а можно примеры?
От: MaximE Великобритания  
Дата: 17.01.05 10:02
Оценка: +1
eao197 wrote:

> В связи с этим у меня вопрос: можно ли услышать/увидеть реальные примеры того, как в многопоточных приложениях обнаруживались проблемы из-за того, что не использовалось volatile? Именно реальные, хорошо бы с примерами, хотя бы псевдокода. И не драйверов или софта для работы с железом, а "прикладного" кода.


С использованием средств синхронизации никаких проблем без volatile нет и быть не должно.

> Просто у меня сложилось такое мнение, что сейчас что с volatile, что без, если используешь штатные средства синхронизации (будь то WinAPI или POSIX), то можно быть спокойным. Более того, разработчики компиляторов не могут не учитывать того факта, что в мире немало программистов (я из их числа), которые не озаботились применением volatile в многопоточном приложении. И если выйдет новая версия компилятора, для которого применение volatile критически важно, то все эти программисты столкнутся с огромным объемом неработоспособного кода. Поэтому можно ожидать, что и в новых компиляторах многопоточные приложения без volatile останутся работоспособными. Но это мое впечатление.


Маловероятно, что кто-то выпустит такой компилятор — его непросто будет продавать, да и tech. support calls разработчикам компилятора не нужны.

--
Maxim Yegorushkin
Posted via RSDN NNTP Server 1.9
Re[3]: [2]: : volatile: а можно примеры?
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 17.01.05 10:48
Оценка: 1 (1)
Максим, я разделяю вашу точку зрения.

Но мне интересно, когда уважаемые emusic, Шахтер, c-smile (извините, если не всех перечислил), отстаивали противоположное мнение, они имели в виду конкретные примеры из собственного опыта или из литературы, или это их интерпритация стардартов и спецификаций? Если примеры есть, то мне было бы очень интересно про них узнать, чтобы не повторять чужих ошибок.

Предложение: давайте не превращать эту ветвь в очередное выяснение истины. Если есть примеры -- приводите, пожалуйста. Если нет, то будем считать это доказательством правильности позиции Максима


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[8]: читаем про volatile
От: Seriously Serious  
Дата: 17.01.05 18:58
Оценка: :)
Здравствуйте, MaximE, Вы писали:

ME>Александреску был публично выпорон


Хочется увидеть аргументы против такого использования volatile
Re[9]: читаем про volatile
От: MaximE Великобритания  
Дата: 17.01.05 20:15
Оценка: 4 (1)
Seriously Serious wrote:

> ME>Александреску был публично выпорон

>
> Хочется увидеть аргументы против такого использования volatile

Ok, как единственный в этой ветке человек, умеющий пользоваться google groups и щелкающий по ссылкам данным здесь же , даю тебе ссылку:

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

--
Maxim Yegorushkin
Posted via RSDN NNTP Server 1.9
Re[9]: читаем про volatile
От: elcste  
Дата: 18.01.05 02:03
Оценка: 13 (2) +1
Здравствуйте, Seriously Serious, Вы писали:

SS>Хочется увидеть аргументы против такого использования volatile


Аргументы в основном сводятся к тому, что experienced multithreaded programmers, которых Александреску упоминает в статье, не станут читать дальше заглавия. Для завсегдатаев comp.programming.threads тема "volatile и multithreaded programming" — нечто вроде красной тряпки для быка. Те же, кто не обратил внимания на название, перестанут читать после примера в первом разделе, когда увидят, что автор ничего не знает о multithreaded programming. Наконец, самые стойкие дочитают до конца и поймут, что им предлагается "an abuse of the type system" (Джеймс Канце) с единственной целью: добиться неопределенного поведения (7.1.5.1/7).
Re[4]: [2]: : volatile: а можно примеры?
От: Шахтер Интернет  
Дата: 18.01.05 03:12
Оценка:
Здравствуйте, eao197, Вы писали:

E>Максим, я разделяю вашу точку зрения.


E>Но мне интересно, когда уважаемые emusic, Шахтер, c-smile (извините, если не всех перечислил), отстаивали противоположное мнение, они имели в виду конкретные примеры из собственного опыта или из литературы, или это их интерпритация стардартов и спецификаций? Если примеры есть, то мне было бы очень интересно про них узнать, чтобы не повторять чужих ошибок.


E>Предложение: давайте не превращать эту ветвь в очередное выяснение истины. Если есть примеры -- приводите, пожалуйста. Если нет, то будем считать это доказательством правильности позиции Максима


Они уже приведены.
... << RSDN@Home 1.1.0 stable >>
В XXI век с CCore.
Копай Нео, копай -- летать научишься. © Matrix. Парадоксы
Re[5]: [2]: : volatile: а можно примеры?
От: MaximE Великобритания  
Дата: 18.01.05 05:14
Оценка:
Шахтер wrote:

[]

> E>Предложение: давайте не превращать эту ветвь в очередное выяснение истины. Если есть примеры -- приводите, пожалуйста. Если нет, то будем считать это доказательством правильности позиции Максима

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

Ok, я не прав был в семантике volatile, привел не удачный пример, и прогнал про sequence points.

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

--
Maxim Yegorushkin
Posted via RSDN NNTP Server 1.9
Re[6]: [2]: : volatile: а можно примеры?
От: Odi$$ey Россия http://malgarr.blogspot.com/
Дата: 18.01.05 05:23
Оценка: 1 (1)
Здравствуйте, MaximE, Вы писали:

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


не вдаваясь в технические подробности, из "недостаточно" никак не может следовать "и поэтому ... бесполезен"
Re[7]: [2]: : volatile: а можно примеры?
От: MaximE Великобритания  
Дата: 18.01.05 05:28
Оценка:
Odi$$ey wrote:

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

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

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

--
Maxim Yegorushkin
Posted via RSDN NNTP Server 1.9
Re[8]: [2]: : volatile: а можно примеры?
От: Odi$$ey Россия http://malgarr.blogspot.com/
Дата: 18.01.05 05:43
Оценка: +2
Здравствуйте, MaximE, Вы писали:

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

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

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


ну, про то что "volatile необходим и достаточен" здесь вообще никто ни разу не сказал, пытались обосновать только, что "необходим",
а вот "недостаточно" "и поэтому ... бесполезен" — это действительно ересь хотя бы с точки зрения формальной логики
Re[9]: [2]: : volatile: а можно примеры?
От: MaximE Великобритания  
Дата: 18.01.05 07:19
Оценка:
Odi$$ey wrote:

[]

> а вот "недостаточно" "и поэтому ... бесполезен" — это действительно ересь хотя бы с точки зрения формальной логики


Согласен, но с точки зрения треда — это оффтопик.

--
Maxim Yegorushkin
Posted via RSDN NNTP Server 1.9
Re[4]: volatile у переменной класса
От: Tom Россия http://www.RSDN.ru
Дата: 18.01.05 08:57
Оценка:
ME>Почитай топик от начала до конца.
Издеваешься? Там толпа мыслей и доводов. Если есть что — говори тут
Народная мудрось
всем все никому ничего(с).
Реальный пример использования volatile
От: What Беларусь  
Дата: 18.01.05 09:00
Оценка:
Здравствуйте, eao197, Вы писали:

E>В связи с этим у меня вопрос: можно ли услышать/увидеть реальные примеры того, как в многопоточных приложениях обнаруживались проблемы из-за того, что не использовалось volatile? Именно реальные, хорошо бы с примерами, хотя бы псевдокода. И не драйверов или софта для работы с железом, а "прикладного" кода.


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

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

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

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


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

21.3005


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

0.00287083


Компилятор VC 7.1. Командная строка:
/O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /FD /EHsc
/MD /GS /Fo"Release/" /Fd"Release/vc70.pdb" /W3 /nologo /c /Wp64 /Zi /TP
... << RSDN@Home 1.1.4 beta 3 rev. 185>>
Re[5]: volatile у переменной класса
От: MaximE Великобритания  
Дата: 18.01.05 09:25
Оценка:
Tom wrote:

> ME>Почитай топик от начала до конца.

> Издеваешься? Там толпа мыслей и доводов. Если есть что — говори тут

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

http://www.rsdn.ru/forum/?mid=989456
Автор: MaximE
Дата: 16.01.05

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

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


--
Maxim Yegorushkin
Posted via RSDN NNTP Server 1.9
Re[6]: volatile у переменной класса
От: Tom Россия http://www.RSDN.ru
Дата: 18.01.05 09:43
Оценка: +1
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.
Народная мудрось
всем все никому ничего(с).
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.