1

I have a thread that captures data from a device. I start/stop the thread from a gui. At the moment, the thread periodically checks a bool member isCapturingEnabled in the appcontext. I toggle this bool member from the gui to stop the thread.

Is this a case where I should use a mutex? Because the capturing thread and the main thread might try to write and read the bool at the same time.

tzippy
  • 6,458
  • 30
  • 82
  • 151
  • 1
    `periodically checks a bool` Why not a condition variable, it is made for these scenarios ? And if it is a single thread, why bother or you aren't revealing everything ? – DumbCoder Mar 10 '15 at 14:40
  • From what you described it sound like the GUI is the only thread that writes to the bool. Is that not the case? – mstbaum Mar 10 '15 at 14:41
  • @mstbaum Actually the capture thread writes too in the case of an exception the threads stops and sets the bool to false – tzippy Mar 10 '15 at 14:44
  • @DumbCoder a condition variable is suitable for waiting, doing nothing, until a condition becomes true - which is a poor use case for a requesting worker threads to terminate - it would be more suitable for the opposite use case - waiting for a worker to finish. – nos Mar 10 '15 at 14:48
  • 1
    How about `std::atomic` for simplicity? http://stackoverflow.com/questions/16111663/do-i-have-to-use-atomicbool-for-exit-bool-variable – piedar Mar 10 '15 at 15:01
  • I concur with the previous commenter. I do not like spinlocks, and mutexes should only be used if atomics do not fit the bill. – Erik Alapää Mar 10 '15 at 16:18

1 Answers1

3

The problem you'll have is that without some sort of locking or memory barrier it is possible (for example) that the gui thread might set the bool to true but the thread won't actually see this due to compiler optimizations or optimizations at the CPU level.

What you need to do is write to the bool in such a way that the current state is loaded from memory, and the new state is correctly written back so that all threads will see the change. One way to do this is with a mutex, as you've identified. Others ways are to use memory barriers to ensure that you're accessing a correct view of memory. Most languages or OSs usually have some sort of API for manipulating memory up to the size of a word in an atomic fashion. For example, on Windows there's the InterlockedCompareExchange function.

However, in 95% of cases just wrapping the read/write in a mutex is good enough from a performance standpoint and is easy to reason about in terms of multithreaded correctness.

Sean
  • 60,939
  • 11
  • 97
  • 136