所以我必须制作一个使用 4 个生产者线程和 4 个消费者线程的程序,并使用一个数组一次保存 10 个随机数。一旦该数组已满,生产者必须等到这 10 个数字被消费者消费完,然后消费者等待数组再次满。我必须使用 1000 个随机数来执行此操作。
问题是程序从未真正完成,我不知道为什么。我正在用 20 个数字对其进行测试,但输出非常困惑且无序,这并没有使这变得更容易。我将把代码和输出放在下面。
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <time.h>
// use 4 cons 4 prod
// instead of random number, use 1000 for all prod
// real time lib is optional
// Due thurs 11pm
using namespace std;
#define BSIZE 10
#define NUM_ITEMS 20
#define NUM_THREADS 8
#define NUM_PRODUCERS 4
#define NUM_CONSUMERS 4
int buf[BSIZE];
int nextin=0, nextout=0;
pthread_mutex_t lock; // a shared lock veriale
pthread_cond_t empty, full;
bool isFull = false, isEmpty = false;
int bufCounter = 0;
void * producer(void *); // function for producer thread
void * consumer(void *); // function for consumer thread
pthread_t tid[NUM_THREADS]; // array of thread IDs
int main( int argc, char *argv[] )
{
int i;
pthread_cond_init(&full, NULL);
pthread_cond_init(&empty, NULL);
printf("\n **** Main Program creating threads **** \n");
for (i = 0; i < NUM_PRODUCERS; i++)
pthread_create(&tid[i], NULL, producer, NULL); // Creating producers
for (i = NUM_PRODUCERS; i < NUM_THREADS; i++)
pthread_create(&tid[i], NULL, consumer, NULL); // Creating consumers
for ( i = 0; i < NUM_THREADS; i++)
pthread_join(tid[i], NULL);
printf("\n *** main() reporting: all %d threads have terminated ***\n\n ", i);
return 0;
} /* main */
void * producer(void * parm)
{
int i, num;
printf("\n ++++ Producer started ++++ \n");
for(i=0; i < NUM_ITEMS; i++)
{ // produce items
num = rand() % 1000;
pthread_mutex_lock(&lock); // lock the buffer when adding num
if (isFull == true)
pthread_cond_wait(&empty, &lock);
buf[nextin++] = num;
nextin %= BSIZE; // make the buffer circular
bufCounter++; // Increment bufCounter
if (bufCounter == BSIZE){
isFull = true;
isEmpty = false;
}
pthread_cond_signal(&full);
pthread_mutex_unlock(&lock); // get out the critical section
}
printf("\n ++++ Producer exiting ++++\n");
pthread_exit(0);
}
void * consumer(void * parm)
{
int i, num;
printf("\n ==== Consumer started ==== \n");
for(i=0; i < NUM_ITEMS; i++)
{
// get item from the buffer and consume it
pthread_mutex_lock(&lock); // lock the buffer when removing item
if (isEmpty == true)
pthread_cond_wait(&full, &lock);
num = buf[nextout++];
nextout %= BSIZE; // make the buffer circular
bufCounter--;
printf(" Consuming item #[%d]: %d\n", i, num);
if (bufCounter == 0){
isEmpty = true;
isFull = false;
}
pthread_cond_signal(&empty);
pthread_mutex_unlock(&lock); // unlock the buffer and get out CS
}
printf("\n ==== Consumer exiting ====\n");
pthread_exit(0);
}
非常感谢任何帮助,而且我知道这里有很多代码。对不起。
编辑:这是完整的输出。
**** Main Program creating threads ****
++++ Producer started ++++
++++ Producer started ++++
++++ Producer started ++++
++++ Producer started ++++
==== Consumer started ====
Consuming item #[0]: 838
Consuming item #[1]: 758
Consuming item #[2]: 113
Consuming item #[3]: 515
==== Consumer started ====
Consuming item #[4]: 51
Consuming item #[5]: 627
==== Consumer started ====
==== Consumer started ====
Consuming item #[6]: 10
Consuming item #[7]: 419
Consuming item #[8]: 212
Consuming item #[9]: 86
Consuming item #[10]: 749
Consuming item #[0]: 225
Consuming item #[11]: 543
Consuming item #[1]: 89
Consuming item #[2]: 84
Consuming item #[3]: 137
Consuming item #[0]: 566
Consuming item #[0]: 183
Consuming item #[1]: 978
Consuming item #[2]: 767
Consuming item #[3]: 495
Consuming item #[4]: 311
Consuming item #[5]: 367
Consuming item #[6]: 54
Consuming item #[7]: 966
Consuming item #[12]: 882
Consuming item #[1]: 736
Consuming item #[2]: 524
Consuming item #[3]: 505
Consuming item #[4]: 60
Consuming item #[5]: 394
Consuming item #[6]: 102
Consuming item #[7]: 851
Consuming item #[8]: 67
Consuming item #[9]: 653
Consuming item #[10]: 561
Consuming item #[11]: 96
++++ Producer exiting ++++
Consuming item #[8]: 31
Consuming item #[9]: 754
Consuming item #[10]: 188
Consuming item #[11]: 85
Consuming item #[12]: 143
Consuming item #[13]: 967
Consuming item #[14]: 145
Consuming item #[15]: 406
Consuming item #[16]: 165
Consuming item #[17]: 403
Consuming item #[4]: 562
Consuming item #[5]: 628
Consuming item #[13]: 920
Consuming item #[14]: 834
Consuming item #[15]: 803
Consuming item #[16]: 444
Consuming item #[6]: 962
Consuming item #[7]: 318
++++ Producer exiting ++++
Consuming item #[8]: 422
Consuming item #[9]: 327
Consuming item #[10]: 457
Consuming item #[11]: 945
Consuming item #[12]: 479
Consuming item #[13]: 983
Consuming item #[14]: 751
Consuming item #[18]: 894
++++ Producer exiting ++++
Consuming item #[19]: 670
==== Consumer exiting ====
Consuming item #[15]: 259
Consuming item #[16]: 248
Consuming item #[17]: 353
Consuming item #[18]: 757
Consuming item #[17]: 629
Consuming item #[18]: 306
Consuming item #[19]: 606
==== Consumer exiting ====
Consuming item #[12]: 990
Consuming item #[13]: 738
Consuming item #[14]: 516
Consuming item #[15]: 414
Consuming item #[16]: 262
++++ Producer exiting ++++
Consuming item #[17]: 116
您可以看到该程序只是停止并停在那里,所以我不确定它是否刚刚处理完所有数字,但它被调用再次等待。
最佳答案
if (bufCounter == BSIZE){
isFull = true;
isEmpty = false;
}
这是错误的。您刚刚将一个项目添加到缓冲区。缓冲区无条件非空。
if (bufCounter == 0){
isEmpty = true;
isFull = false;
}
同样,您刚刚从缓冲区中删除了一个项目。它无条件地不完整。
在这两种情况下,其中一个赋值应该在 if
之外。 OTOH 如果状态没有改变,则不需要向 condvar 发出信号,因此 pthread_cond_signal
应该移到 if
中。
最后,如果您使用 C++ 编写,请使用 C++ 工具。 C++ 现在支持多线程,因此无需求助于特定于操作系统的 API。
Here是固定程序,经过最低限度的更改使其成为 C 程序。
关于c++ - 生产者消费者 pthreads 程序未完成,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46839413/