【发布时间】:2020-10-15 04:00:18
【问题描述】:
我有一个生产者和两个消费者线程试图访问共享缓冲区。消费者和生产者之间使用互斥锁。消费者应该并行运行。如果缓冲区为空,则消费者休眠,生产者必须唤醒它们。如果缓冲区已满,生产者不做任何事情。下面是我正在处理的代码 sn-ps: 生产者线程:
void *writer(void*)
{
// Initialising the seed
srand(time(NULL));
while(1)
{
pthread_mutex_lock(&rallow);
if (Q.size() < MAX && item < MAX)
{
// Getting the random number
int num = rand() % 10 + 1;
// Pushing the number into queue
Q.push(num);
item++;
cout << "Produced: " << num << " item: "<<item<<endl;
pthread_cond_broadcast(&dataNotProduced);
}
else if (item == MAX) {
pthread_mutex_unlock(&rallow);
continue;
}
pthread_mutex_unlock(&rallow);
}
}
消费者 1:
void *reader1(void*)
{
while(1)
{
pthread_mutex_lock(&mread);
rc++;
if(rc==1)
pthread_mutex_lock(&rallow);
pthread_mutex_unlock(&mread);
if (Q.size() > 0) {
// Get the data from the front of queue
int data = Q.front();
// Pop the consumed data from queue
Q.pop();
item--;
cout << "B thread consumed: " << data <<endl;
pthread_cond_signal(&dataNotConsumed);
}
else
{
cout << "B is in wait.." << endl;
pthread_cond_wait(&dataNotProduced, &rallow);
cout<<"B woke up"<<endl;
}
pthread_mutex_lock(&mread);
rc--;
if(rc==0)
pthread_mutex_unlock(&rallow);
pthread_mutex_unlock(&mread);
sleep(1);
}
}
消费者2:
void *reader2(void*)
{
while(1)
{
pthread_mutex_lock(&mread);
rc++;
if(rc==1)
pthread_mutex_lock(&rallow);
pthread_mutex_unlock(&mread);
if (Q.size() > 0) {
// Get the data from the front of queue
int data = Q.front();
// Pop the consumed data from queue
Q.pop();
item--;
cout << "C thread consumed: " << data <<endl;
pthread_cond_signal(&dataNotConsumed);
}
else
{
cout << "C is in wait.." << endl;
pthread_cond_wait(&dataNotProduced, &rallow);
cout<<"C woke up"<<endl;
}
pthread_mutex_lock(&mread);
rc--;
if(rc==0)
pthread_mutex_unlock(&rallow);
pthread_mutex_unlock(&mread);
sleep(1);
}
}
输出看起来像这样:
C is in wait..
B is in wait..
Produced: 8 item: 1
Produced: 4 item: 2
Produced: 2 item: 3
Produced: 4 item: 4
Produced: 2 item: 5
Produced: 8 item: 6
Produced: 5 item: 7
Produced: 2 item: 8
Produced: 10 item: 9
Produced: 3 item: 10
>> Producer is in wait..
B woke up
B thread consumed: 8
B thread consumed: 4
B thread consumed: 2
B thread consumed: 4
B thread consumed: 2
B thread consumed: 8
B thread consumed: 5
B thread consumed: 2
B thread consumed: 10
B thread consumed: 3
B is in wait..
C woke up
C is in wait..
Producer woke up
我怀疑为什么线程 B 和 C 没有显示并行执行。以及为什么生产者一次将值填充到缓冲区 10 中,而不是提供少量,然后消费者消费它,然后再次产生少量。任何线索将不胜感激。
【问题讨论】:
-
考虑操作系统为每个线程分配时间片。生产者可以在其中一个消费者获得时间片之前将多个项目放入队列中。类似地,单个消费者可能会在另一个消费者有机会之前将多个项目出列。即使每个线程都在单独的内核上运行,也不能保证它们都以完全相同的速度运行。
-
顺便说一句,如果您有两个几乎相同的函数,请考虑将公共部分分解为一个两个都可以调用的函数。另外,您正在编译哪个 c++ 版本?从c++11开始就有
std::thread,不需要联系那些可怕的void*s -
@G.Sliepen 我明白你所说的。但是看看输出程序给了我,我看到一旦一个线程锁定到互斥锁,它也会在接下来的几次中获得互斥锁。当前线程在传递给任何其他线程之前获得了显着的互斥量。我该如何克服这个问题?
标签: c++ multithreading mutex