生产者消费者需要多个互斥锁才能访问关键部分?

时间:2014-03-10 09:07:38

标签: c multithreading pthreads producer-consumer

有3个工具。消费者需要2个工具来修改缓冲区。如果消费者A使用2个工具而消费者B需要1个,消费者B将不得不等待另一个工具被释放。

我不确定我是否以正确的方式思考这个问题。我解释它的方式是我需要3个互斥量而消费者必须锁定2个3,这是正确的想法吗?

我认为我不应该使用信号量,因为我不希望多个线程同时访问共享资源。在正常的生产者消费者问题中,只有1个互斥锁,但在这里我需要3个中的任何2个如何处理它?<​​/ p>

2 个答案:

答案 0 :(得分:0)

是的,您可以使用3个互斥锁,但必须小心避免死锁。为此,您必须建立一个众所周知的订单来获取锁:例如,始终首先获取具有最低标识符的工具的锁。在这种情况下,避免死锁始终是以相同的顺序获取锁定的问题。

一些伪代码:

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();
}

这假设您将ID与0-2范围内的每个工具相关联。

但请注意,如果您愿意,只有一个生产者/消费者可以同时工作,因为只有3个工具。因此,您可能希望使用单个互斥锁,锁定它,获取2个工具,完成工作并释放它 - 毕竟,并行性的可能性不大,您最多只能有一个生产者/消费者工作,其他人等着拿着1个工具。

答案 1 :(得分:0)

那么,首先要看看你的共享资源是什么? 工具当然。现在有三种工具,其中有两种需要做工作。因此,每当消费者想要获取工具时,我们都需要小心。假设函数AcquireTools()将工具分配给消费者。现在这很容易解决。 首先,我们声明一个全局变量mutex并将其初始化为1.然后,

wait(mutex);   
AcquireTools();
//do work
signal(mutex);

假设consumerA想要这两个工具,它会调用wait(mutex)并且mutex的值会更改为0。现在,当consumerA正在工作时,consumerB想要这两个工具。它会调用wait(mutex),但会调用mutex=0的值,因此在consumerA信号和mutex的值更改回1之前,它无法继续。