我正在尝试用 C 解决多个生产者/消费者问题,但它没有按预期工作。下面是一些伪代码来代表我的实现。
Thread thread1;
Thread thread2;
Thread thread3;
Data data1;
Mutex data1_mutex;
Semaphore data1_empty;
Semaphore data1_fill;
Data data2;
Mutex data2_mutex;
Semaphore data2_empty;
Semaphore data2_fill;
thread1()
{
// creates data and places it into data1.
wait(data1_empty);
lock(data1_mutex);
// critical section
unlock(data1_mutex);
post(data1_fill);
}
thread2()
{
// Removes data from data1, processes it, and places it into data2.
// data1
wait(data1_fill);
lock(data1_mutex);
// data2
wait(data2_empty);
lock(data2_mutex);
// critical section
// data2
unlock(data2_mutex);
post(data2_fill);
// data1
unlock(data1_mutex);
post(data1_empty);
}
thread3()
{
// Removes data from data2, prints its results, and removes it.
wait(data2_fill);
lock(data2_mutex);
// critical section
unlock(data2_mutex);
post(data2_empty);
}
但是,使用此解决方案,data1 将填满,但 thread2 将锁定并且永远不会运行。我的实现有问题吗?
编辑#1
我发现的问题之一是我的第二个互斥体没有正确创建。我不知道它出了什么问题,所以我只是对所有线程使用第一个互斥体。我还做了其他一些事情来让它工作,所以稍后当我有时间时我将更新我的伪代码以反射(reflect)这一点。
最佳答案
如果您对 Data
使用某种排队类型,则应该能够完全删除“空”信号量,除非您试图强加每个 Data
队列深度严格为 0 或 1。如果在 thread2
中使用局部变量,则可以减小临界区的大小。
代码就会变成这样:
thread1() {
//Wait for data to put in the queue (i.e. a blocking socket read)
lock(data1_mutex);
data1.push(someData);
unlock(data1_mutex);
post(data1_fill);
}
thread2() {
DataType dataElement;
wait(data1_fill);
lock(data1_mutex);
dataElement = data1.pop();
unlock(data1_mutex);
lock(data2_mutex);
data2.push(dataElement);
unlock(data2_mutex);
post(data2_fill);
}
thread3() {
DataType dataElement;
wait(data2_fill);
lock(data2_mutex);
dataElement = data2.pop();
unlock(data2_mutex);
//do something with dataElement here
}
关于c - 多个生产者/消费者和临界区代码问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1408047/