多个生产者/消费者和临界区代码问题
我正在尝试用 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
我发现的问题之一是我的第二个互斥体没有正确创建。我不知道它出了什么问题,所以我只是对所有线程使用第一个互斥体。我还做了其他一些事情来让它工作,所以稍后当我有时间时我将更新我的伪代码以反映这一点。
I am attempting a multiple producer/consumer problem in C, but its not working as expected. The following is some pseudo code to represent my implementation.
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);
}
However, with this solution data1 will fill up, but thread2 will lock and never run. Is there something wrong with my implementation?
EDIT #1
One of the problems I found was that my second mutex was not being created correctly. I don't know what's wrong with it so I'm just using the first mutex for all threads. There is also something else I have done to get it working, so I'll update my pseudo-code to reflect this later when I have a minute.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
如果您对
Data
使用某种排队类型,则应该能够完全删除“空”信号量,除非您试图强加每个Data
的条件队列深度严格为 0 或 1。如果在thread2
中使用局部变量,则可以减小临界区的大小。然后代码就变成这样:
If you use some sort of queuing type for
Data
, you should be able to remove the "empty" semaphores completely, unless you're trying to impose the condition that eachData
queue depth is strictly 0 or 1. If you use a local variable inthread2
, you can reduce the size of the critical section.The code then becomes something like this:
确保您最初发布
data1_empty
和data2_empty
。Make sure you post
data1_empty
anddata2_empty
initially.wrang-wrang 所说的,在等待 data_2_empty 时尽量不要持有 data_1 的锁。您可以通过为交换出的 data_1 和 data_2 保留备用缓冲区来实现此目的。 Thread_2 在处理 data_1 时将其交换到 data_2,thread_3 在处理时将 data_2 交换出。您当前的伪代码将允许线程 1 和线程 3 并发运行,但不允许线程 2 与其他线程同时执行。
What wrang-wrang said, and try not to hold the lock for data_1 while you're waiting for data_2_empty. You could achieve this by keeping an alternate buffer for data_1 and data_2 that you swap out. Thread_2 swaps data_1 while processing it into data_2, thread_3 swaps out data_2 while processing it. Your current pseudo-code will allow thread 1 and thread 3 to run concurrently, but it won't allow thread 2 to execute at the same time as either of the others.