Is it useful to mark variables as volatile if they are shared across threads? [duplicate]

断了今生、忘了曾经 提交于 2019-12-07 09:55:04

问题


Notice!

I'm obviously failing to make my point clearly to everyone here, and it's incredibly frustrating. My goal was to dispel the myth that volatile is effectively a no-op, that it does nothing. I was not trying to state that it should be used, that it is essential, that it is not redundant, etc.

I have shown that volatile does still do a thing. I concede that it is redundant under certain circumstances, and that the multi-threaded example was a poor choice.

I am also not trying to hide the fact that my answer's initial revisions contained errors. But this Q&A is not even coming close to fulfilling its intended purpose. To that end, I think it's time to chuck it away.

Thanks to Kerrek and T.C. for their insights. I just don't think their responses fit the question that I wanted to ask. I'm sure that's my fault for asking it poorly.

Therefore I am abandoning it! And closing it as a duplicate of the question not that it was intended as, but that it has been interpreted as.

Cheers! (& hth.)

I am writing to a variable in one thread and reading from it in another. I have been told that volatile is completely useless for this and that I do not need to use it in this day and age unless I am working with hardware.

int x = 0;
void thread1()
{
   while (true) {
      sleep(1);
      if (x > 0)
         break;
   }
}

void thread2()
{
   while (true) {
      sleep(1);
      x++;
   }
}

Do I gain anything by using volatile in this case?
And how about if x is not a simple int but a class type?


回答1:


You have been told correctly, volatile is not useful for inter-thread communication. Don't use it for that purpose. It does not provide synchronization and leaves your code with data races. Conversely, when synchronizing access to shared state correctly, you do not need volatile.

The correct code that Does What You Mean uses atomic variables for the shared state or protects the shared state with a mutex, and the shared state will be observed correctly by all threads. For example:

#include <atomic>

std::atomic<int> x = 0;

void thread1()
{
   while (true) {
      sleep(1);
      if (x > 0)
         break;
   }
}

void thread2()
{
   while (true) {
      sleep(1);
      x++;
   }
}

At no point is there any need for volatile.

Note that volatile may be useful within a thread to enforce that a loop that otherwise has no side effects is evaluated:

// Spend some time
for (volatile int i = 0; i != LARGE_NUMBER; ++i)
{ /* do nothing */ }

// or even:
for (int i = 0; const_cast<volatile int &>(i) != LARGE_NUMBER; ++i) {}


来源:https://stackoverflow.com/questions/29107888/is-it-useful-to-mark-variables-as-volatile-if-they-are-shared-across-threads

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