c - 多个生产者/消费者和临界区代码问题

标签 c producer-consumer critical-section

我正在尝试用 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/

相关文章:

c - C中的长数据类型计算

c - Do...While 逻辑运算符循环

java - 为什么我不能使用原语作为同步部分的互斥体?

c++ - Windows 上互斥量、临界区等的成本

multithreading - Delphi线程: CriticalSection not being "Release' d"when using Synchronize inside its method

c - 我是否必须为 C 中的每对进程创建一个新管道?

c - 当 'zsh' shell 运行 "cat < 11 < 22 < 33 > 55 > 66"时,它使用什么算法?

c++ - 在同一个互斥量上使用两个 std::unique_lock 会导致死锁?

java - 如何创建消费者生产者队列

c++ - C++中的无锁多生产者多消费者