Add another ofMutex to ofThread subclass

Let’s say I have two queues

std::list<data> queueA;
std::list<data> queueB;

And I want the main thread and my own ofThread to use them at will. If I use the lock() and unlock() methods for all uses of these two queues, they will both be locked anytime I want to use one of them. How could I lock only one of the queues?

I’m guessing I could add another ofMutex element, and use lock() unlock() for queueA, and the other mutex for queueB,

I don’t know if I’m making too many assumptions on what the mutex does.

Best!

that should work but when using 2 mutexes from 2 threads you need to be extra careful with deadlocks as it’s really easy to get to a situation where:

thread 1 locks A
thread 2 locks B
thread 1 tries to lock A
thread 2 tries to lock B

then both threads are locked forever, so in general do not lock both mutexes at the same time. Also depending what you are trying to do it might be possible that you can access both queues lock free and then only use one lock to swap them at a certain point, using some kind of double or triple buffering

1 Like

Thanks!! From what I’ve seen it might be better to make a class that holds the queue and has its own mutex. for that queue, and locks whenever any thread tries to operate on it.

I guess that would avoid deadlocks as this Queue class would never lock any other resource from within a lock.

I eventually coded this, it is a lot faster than using lock and unlock in a derived ofThread class for queue access. Use with caution!

#pragma once
#include "ofThread.h"

template <typename T>
class ofxMutexQueue
{
public:
	ofxMutexQueue(void)
	{
	}

	~ ofxMutexQueue(void)
	{
	}

	int size()
	{
		mutex.lock();
		int size = queue.size();
		mutex.unlock();
		return size;
	}


	void clear()
	{
		mutex.lock();
		queue.clear();
		mutex.unlock();
	}


	T popElement()
	{
		mutex.lock();
		T element = queue.front();
		queue.pop_front();
		mutex.unlock();
		return element;
	}

	void pushElement(T element)
	{
		mutex.lock();
		queue.push_back(element);
		mutex.unlock();
	}

private:
	ofMutex mutex;//Poco::FastMutex, take care of deadlocks!!
	list<T> queue;
};