Can I use mutex or key word(static) instead of volatile in C++?

一个人想着一个人 提交于 2019-12-24 01:33:14

问题


I know how volatile works in C++. However, I'm still feeling confused about why we need volatile. Only reason I think is we need listen whether the variable changed, as the code shows below:

volatile int some_int = 100;

while(some_int==100) {
    doSomething()
}

The programmer needs know if the word some_int changed, so he uses "volatile". Could I use the key word "static" instead?

Mostly, I think we should we mutex(lock) to synchronize if synchronization is necessary in multi-thread. Excuse my poor English:)


回答1:


The programmer needs know if the word some_int changed, so he uses "volatile". Could I use the key word "static" instead

volatile was used in C++98 in concurrent programming because C++ did not support multi-threading as language at that time and side effects of volatile helped to avoid some race conditions, though there were no guarantees it would/should work. Since C++11 there are tools to work with concurrent programming properly - std::mutex and std::atomic, so you should stop using volatile for wrong purpose. Making variable static is completely unrelated and would not affect existence of side effects directly.




回答2:


The volatile keyword is intended to prevent the compiler from applying any optimizations on objects that can change in ways that cannot be determined by the compiler. Objects declared as volatile are omitted from optimization because their values can be changed by code outside the scope of current code at any time. https://www.geeksforgeeks.org/understanding-volatile-qualifier-in-c/

As a long time embedded systems programmer, my perspective is that the volatile qualifier is a 'command' from me to the compiler. On an address-by-address basis, I "order" the compiler to always perform every access I code. The compiler accomplishes this by preventing certain code optimizations.

why we need volatile

In memory-mapped i/o (as opposed to port i/o), my code dealt with feedback from hardware devices, indicating, for example, "transfer complete", or "buffer full", or "los" (loss-of-signal). Each has their own urgency.

High urgency would often notify the software with an interrupt (and almost never a 'polling', as in your example). The hardware design often provides some buffering support, giving the software more time to respond to the interrupt. In an interrupt handler, the compiler must not optimize away any hardware reads or writes. Volatile use required.

Lower urgency is often handled by periodic status checks (again, never by polling). Historically the telecom "los" is checked once per second. This enables the software to report the system alarm within the required 2.5 +/- 0.5 seconds (after the los started).

The los-bit check must never be skipped. The keyword volatile commands the compiler to not remove the code doing the checking, no matter how recently the software looked at the bits. Volatile use required.

In this context, a semaphore or atomic will not work ... the hardware I have worked on does not know those concepts. Volatile required.


Could I use the key word "static" instead?

No.


This is a wasteful poll:

volatile int some_int = 100;

while(some_int==100) {
    doSomething()
}

Never do this.


This is a (much simplified) status update:

// status update thread 
do
{
    waitFor_startOfSecond();  // os provided call

    // status check
    if (los(bit))   // test the los bit in hw (1 of 10000)
    {
       losActions()
    }

    // ... other stuff, including other status bits

    // Note: expect less than 1 second elapsed since start of loop
    // On at least one system, this alarm processing effort 
    // completed in < 1/3 second  (even ~10,000 alarms)

} while(1); // typically, embedded threads do not halt



回答3:


Mostly, I think we should we mutex(lock) to synchronize if synchronization is necessary in multi-thread.

You're right.

And, if you have mutexes, you don't need volatile (as the load guarantees are already there).

The programmer needs know if the word some_int changed, so he uses "volatile".

That's true, or at least it would be if some_int were instead some value provided by a piece of hardware, or some other part of the computer, not under your program's control. Your program can't tell when such a value has been changed externally.

Like:

volatile int* ptr_to_some_int = 0x0123456; // hardcoded address to somewhere magical!

printf("%d", *ptr_to_some_int); // okay, we'll get some value

// But the value of *ptr_to_some_int may have changed here...

printf("%d", *ptr_to_some_int); // ... so here it must be assuredly reloaded

I'm still feeling confused about why we need volatile.

If the above is not the case, then you don't.

Could I use the key word "static" instead?

No, static is completely unrelated.



来源:https://stackoverflow.com/questions/49154567/can-i-use-mutex-or-key-wordstatic-instead-of-volatile-in-c

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!