Search code examples
cmultithreadingpthreadsproducer-consumer

Producer consumer multiple mutex needed to access critical section?


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?


Solution

  • 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.