4

I am passing few variables by pointer (cv::Mat's and bool's) to several threads and am trying to understand when it is necessary to use mutex. I have found that without using it on the cv::Mat's, my program will crash (likely because one thread is writing to the same area of memory that the other is reading from), so I have implemented mutex for these variables and it has fixed the problem.

But now the mutex is one more variable I am passing by pointer to each thread. So in this case, the use of the handling of the mutex variable is the same as the other variables I need to mutex, so what's so special about the mutex that I wouldn't need a mutex as well (and of course that goes on forever and the conept doesn't work).

To be clear, the code I have works fine, this is more for educational purposes.

Example:

//Common frames 
cv::Mat captureimage, displayimage;
std::mutex capturemutex, displaymutex;

//Start image capture thread
std::thread t_imagecapture( CaptureImageThread, &captureimage, &capturemutex, &exitsignal );
//Start image processor thread
std::thread t_imageprocessor( ProcessImageThread, &captureimage, &capturemutex, &exitsignal );
//Start display thread
std::thread t_displayupdate( DisplayUpdateThread, &displayimage, &displaymutex, &exitsignal );
DrTarr
  • 922
  • 2
  • 15
  • 34
  • 3
    Usually it's enough to have one mutex for all variables shared between threads. – πάντα ῥεῖ Sep 02 '16 at 11:47
  • 1
    Mutexes are designed to be threadsafe by themself. They use underlying mechanisms of the operating system, which guarantees that you will have no race conditions when locking/unlocking mutexes. – Hayt Sep 02 '16 at 11:48
  • 3
    "I have implemented mutex for these variables" -- no, you haven't **implemented** a mutex; you've **used** a mutex. – Pete Becker Sep 02 '16 at 12:00
  • Regarding using unique mutexes for each variable versus a common mutex, wouldn't there be a performance gain with multiple mutexes? For example, in this application I do not wish for the t_displayupdate thread to wait to read displayiamge while t_imagecapture thread is writing the capture image. – DrTarr Sep 02 '16 at 12:20
  • You can get some performance gain if the data structures protected by these mutexes has completely unrelated treatment. Otherwise, if you need to acquire two or more mutexes at once you easily may get a deadlock, see https://en.wikipedia.org/wiki/Deadlock – Serge Sep 02 '16 at 12:46

1 Answers1

5

A mutex is an atomic lock. It uses lowlevel methods (CPU), for example, it could test-and-set the lock without being interrupted, so it doesn't need an external lock to perform this. And once the lock is set, no other thread can do that, so the mutex can protect the access of other resources.

stefaanv
  • 14,072
  • 2
  • 31
  • 53
  • Yes, I didn't think I needed to point out all the implementations. I don't even know all the implementations, so I'll edit to highlight that. – stefaanv Sep 02 '16 at 11:58
  • Thanks! Also, [this](http://preshing.com/20130618/atomic-vs-non-atomic-operations/) site was helpful for explaining atomic operations. And the topic of atomic operations, reading [this](http://stackoverflow.com/questions/9200951/is-it-ok-to-read-a-shared-boolean-flag-without-locking-it-when-another-thread-ma) thread makes it sound like I need to use std::atomic for my boolean variables. – DrTarr Sep 02 '16 at 12:27
  • Yes, atd::atomic is a game changer when working multi-threaded. Mutexes are still needed when more code needs to be done atomically or more complex resources must be protected. – stefaanv Sep 02 '16 at 12:30