86947

Use “regular” variable to synchronize threads

Question:

If I have only two threads, and I want one of them to wait for the other to reach a certain point, is it safe to do the following:

bool wait = true; //Thread 1: while(wait) ; wait = true; //re-arm the signal //Thread 2: /* Preform here the code that needs to complete before Thread 1 continues */ wait = false;

Basically, if one thread only writes to it and the other only reads, can there be a problem? I assume a read or a write of a single bool is atomic, and even if not, I don't see how it can make a difference here.

Answer1:

No, it can't work. If you use std::atomic<bool> instead it will work.

Atomics in C++ address three issues. First, the possibility that a thread switch will happen in the middle of storing or reading a value that requires more than one bus cycle; this is called "tearing". Second, the possibility that two threads will be running on two separate processors with two separate caches, and one thread won't see changes made by the other. This is called "cache coherency". Third, the possibility that the compiler will move code around because the order doesn't appear to matter.

Even though a bool value probably only requires one bus cycle to read or write, it doesn't address the other two issues.

There are no reliable shortcuts. Use proper synchronization.

Answer2:

While you would get guarantees with an std::atomic<bool>, I think you could perhaps make it work with a simple volatile, because:

<ul><li>the compiler cannot reorder instructions on volatile values</li> <li>one of the threads always write to the variable, so the instruction is effectively atomic</li> <li>the other thread doesn't need to do the read and the write atomically </li> </ul>

So there wouldn't be any form of tearing. However, the issue of cache coherency is still there, and that's hardware or OS dependent.

Recommend

  • Concurrency scenarios with INSERTs
  • Use MongoDB array as stack
  • How atomic are mongoengine's operations
  • if some function is not optimized does it mean that all functions where it is declared are not optim
  • runtime-check whether an instance (Base*) override a parent function (Base::f())
  • Building Qt project for C++11 standard
  • C++ friend class std::vector
  • Error in installing package: fatal error: stdlib.h: no such file or directory
  • cordova is not defined - cordova.js has already been loaded :: Ionic
  • jQuery: add elements until a particular height is reached
  • Find group of records that match multiple values
  • Hide HTML elements without javascript, only CSS
  • Combining two different ActiveRecord collections into one
  • Java color detection
  • Copy to all folders batch file?
  • zope_i18n_compile_mo_files doesn't work on a Zeo configuration
  • OOP Javascript - Is “get property” method necessary?
  • How to use carriage return with multiple line?
  • Moving mysql files across servers
  • Scrapy recursive link crawler
  • Email format validation in mvc3 view
  • Sails.js/waterline: Executing waterline queries in toJSON function of a model?
  • C# - Is there a limit to the size of an httpWebRequest stream?
  • How to add date and time under each post in guestbook in google app engine
  • Running a C# exe file
  • Join two tables and save into third-sql
  • How to model a transition system with SPIN
  • Redux, normalised entities and lodash merge
  • ORA-29908: missing primary invocation for ancillary operator
  • Do create extension work in single-user mode in postgres?
  • R: gsub and capture
  • jqPlot EnhancedLegendRenderer plugin does not toggle series for Pie charts
  • Comma separated Values
  • InvalidAuthenticityToken between subdomains when logging in with Rails app
  • SQL merge duplicate rows and join values that are different
  • coudnt use logback because of log4j
  • LevelDB C iterator
  • Can't mass-assign protected attributes when import data from csv file
  • Converting MP3 duration time
  • How to load view controller without button in storyboard?