前言:我是多线程编程的新手,对 C++ 有点生疏。我的要求是使用一个互斥锁和两个条件 mNotEmpty
和 mEmpty
.我还必须按照下面提到的方式创建和填充 vector 。
我有一个生产者线程创建一个大小为 n*2
的随机数 vector ,以及两个消费者将这些值插入到两个大小为 n
的独立 vector 中.
我在制作人中执行以下操作:
- 锁定互斥量:
pthread_mutex_lock(&mMutex1)
- 等待消费者说 vector 为空:
pthread_cond_wait(&mEmpty,&mMutex1)
- 将一个值推回到 vector 中
- 通知消费者 vector 不再为空:
pthread_cond_signal(&mNotEmpty)
- 解锁互斥量:
pthread_mutex_unlock(&mMutex1)
- 回到第一步
在消费者中:
- 锁定互斥量:
pthread_mutex_lock(&mMutex1)
- 检查 vector 是否为空,如果是则向生产者发出信号:
pthread_cond_signal(&mEmpty)
- 否则将值插入两个新 vector 之一(取决于哪个线程)并从原始 vector 中删除
- 解锁互斥量:
pthread_mutex_unlock(&mMutex1)
- 回到第一步
我的流程有什么问题?我不断收到段错误或无限循环。
编辑:这是代码:
void Producer()
{
srand(time(NULL));
for(unsigned int i = 0; i < mTotalNumberOfValues; i++){
pthread_mutex_lock(&mMutex1);
pthread_cond_wait(&mEmpty,&mMutex1);
mGeneratedNumber.push_back((rand() % 100) + 1);
pthread_cond_signal(&mNotEmpty);
pthread_mutex_unlock(&mMutex1);
}
}
void Consumer(const unsigned int index)
{
for(unsigned int i = 0; i < mNumberOfValuesPerVector; i++){
pthread_mutex_lock(&mMutex1);
if(mGeneratedNumber.empty()){
pthread_cond_signal(&mEmpty);
}else{
mThreadVector.at(index).push_back[mGeneratedNumber.at(0)];
mGeneratedNumber.pop_back();
}
pthread_mutex_unlock(&mMutex1);
}
}
最佳答案
我不确定我理解你这样做背后的基本原理 事物。在通常的消费者-提供者惯用语中,提供者推送为 尽可能多的元素进入 channel ,只有在有的时候才等待 channel 空间不足;它不等待空。所以 通常的成语是:
提供者(推送一项):
pthread_mutex_lock( &mutex );
while ( ! spaceAvailable() ) {
pthread_cond_wait( &spaceAvailableCondition, &mutex );
}
pushTheItem();
pthread_cond_signal( &itemAvailableCondition );
pthread_mutex_unlock( &mutex );
在消费者方面,获取一个项目:
pthread_mutex_lock( &mutex );
while ( ! itemAvailable() ) {
pthread_cond_wait( &itemAvailableCondition, &mutex );
}
getTheItem();
pthread_cond_signal( &spaceAvailableCondition );
pthread_mutex_unlock( &mutex );
请注意,对于每种情况,一方发出信号,另一方等待。 (我
在你的消费者中没有看到任何等待。)如果有不止一个
任何一方的过程,我建议使用 pthread_cond_broadcast
,
而不是 pthread_cond_signal
。
您的代码中还有许多其他问题。有些看起来更
比如拼写错误:您应该复制/粘贴实际代码以避免这种情况。你
真正的意思是当你插入时读取并弹出mGeneratedValues
mGeneratedNumber
,检查是否为空? (如果你真的
确实有两个不同的队列,然后你从一个没有队列的队列中弹出
一个已经推了。)而且你没有任何循环等待
状况;你不断迭代你的元素数量
期望(每次增加计数器,所以你很可能
早于你应该发芽) - 我看不到无限循环,
但我可以很容易地在 pthread_cond_wait
中看到无休止的等待
制作人。我没有立即看到核心转储,但是当一个
进程终止(可能是消费者,因为它从不
等待任何事情);如果它最终破坏了互斥量或条件
变量,当另一个进程试图
使用它们。
关于c++ - 一个生产者,两个消费者作用于生产者产生的一个 'queue',我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9822829/