Ok, I’ve a application which has two additional threads.
Thread one accesses object O and inserts data into a deque which is part of object O and increments a counter variable.
Thread two accesses object O and pulls out and deletes data from the deque and decrements the counter variable.
This turned out to give unexpected results since one thread tells me there are x elements inside of the deque and the other thread tells me there are no elements. I assume I have to use some kind of synchronization. I tried to use semaphore which I must have misunderstood since it didn’t work (http://msdn.microsoft.com/en-us/library/windows/desktop/ms686946(v=vs.85).aspx).
So I want to know how to access a global object from two threads. Be aware that the access to the global object O happens quite often since the access is within a while loop which results in continues insertions and polls. (Would the possible solution block the other thread from accessing the object and therefore the while loop?)
So far I only know of semaphore and mutex but have never used any of them, please be so kind and enlighten me.
When accessing an object from multiple threads with one access possibly changing the object, you need some from of synchronization. For the scenario described you probably want to have a queue class which does the necessary thread protection and signalling. Here is a simple implementation:
The code uses C++ 2011 constructs but it can easily be changed to avoid their use and rather use C++ 2003 constructs instead except that these aren’t standardized.
The key points are:
std::mutexis used to make sure only on thread accesses the queue at a time.trueandwait()returns immediately, otherwise the thread is put to sleep until it gets a signal at which point the condition is reevaluated. Note, that the condition may be evaluated multiple times because there may be spurious wake-up to the condition variable.this; member variables cannot be captured directly because they are not part of the local context.pop()is returned by value: the moment the lock gets release, the container may be changed, making it impossible to return objects by reference, even if they were put into a suitable location.The main reason this is somewhat of a toy example is that it doesn’t have a nice way to shut down the system: If a thread is blocked on the queue it waits until there is another object. A real implementation would have some way to signal that it is time to shut down, possibly throwing an exception from
pop(). Also, sometimes it is useful to have queue which doesn’t force blocking to extract an object. Instead, it would have a functiontry_pop()which acquires a lock, checks if the queue is non-empty and depending on the result extracts and object or signals failure. A function like this is easy to implement, though.