There are 3 tools. A consumer needs 2 tools to modify the buffer. If consumer A takes the 2 tools and consumer B takes 1, consumer B will have to wait for another tool to be released.
I am not sure if I'm thinking about this problem in the right way. The way I interpret it is that I need 3 mutex and the consumer has to lock 2 out 3, is this the right idea?
I don't think I should be using semaphores because I don't want multiple threads accessing a shared resource at the same time. In a normal producer consumer problem there is just 1 mutex lock but here I need any 2 of the 3 how do I approach this?
Yes, you can use 3 mutexes, but you must be careful to avoid deadlock. To do so, you must establish a well known order to acquire locks: for example, always acquire the lock for the tool with the lowest identifier first. In situations like these, avoiding deadlock is always a matter of acquiring locks in the same order.
Some pseudo-code:
pthread_mutex_t locks[3]; // 1 lock for each tool
critical_function() {
/* Acquire 2 tools, t1 and t2 */
first = min(t1, t2);
second = max(t1, t2);
locks[first].lock();
locks[second].lock();
/* Do work... */
locks[first].unlock();
locks[second].unlock();
}
This assumes that you associate an ID to each tool in the range 0-2
.
But notice, if you will, that no more than one producer / consumer can be working at the same time, since there are 3 tools only. So you might want to use a single mutex instead, lock it, acquire 2 tools, do the work and release it - after all, there is not much possibility for parallelism, you will have at most one producer / consumer working, and the others waiting while holding 1 tool.