算法习题34:生产者消费者队列(多线程编程)

来源:互联网 发布:windows sublime git 编辑:程序博客网 时间:2024/05/22 00:52
实现一个队列。
队列的应用场景为:

一个生产者线程将int类型的数入列,一个消费者线程将int类型的数出列

-------------------------------------------------

这道题比较容易,就是一个队列的实现,

这里我用面向对象的结构来写,一个Queue类有生产和消费的方法,里面内部结构是队列

这里我用的是g++编译环境

用的库是POSIX兼容的

就是生成两个线程然后执行消费生产行为 ,这里需要用到一个锁(互斥量)

但是这个程序运行多次发现有时候会陷入死循环,不知是不是发生了死锁,希望有人能指出问题所在

找到原因了!

是我这里的队列出了问题,Consume()函数

如果刚好尾部与头部相遇的时候,我没有判断,仍然执行rear = reae->next;

这里没错,然后我执行了delete temp;也没错,可是front呢?他仍然指向被释放的那块资源,所以这里就出现问题了

Consume改程如下

int Consume(){if(rear == NULL)return -1;size--;int result = rear->value;Node* temp = rear;//这一步很重要/* * 如果这个时候刚好到达尾部,那么必须清空 */if(rear == front){rear = NULL;front = NULL;}else{rear = rear->next;}delete temp;return result;}

我就不直接在源程序上改动了,参考的朋友希望你们注意下这个问题!

//============================================================================// Name        : QueueProducerAndConsumer.cpp// Author      : YLF// Version     :// Copyright   : Your copyright notice// Description : Hello World in C++, Ansi-style//============================================================================#include <iostream>#include <pthread.h>using namespace std;#define MAX 50struct Node{int value;Node* next;};class Queue{private:Node* front;Node* rear;int size;public:Queue(){front = NULL;rear = NULL;size = 0;}void Produce(int value){size++;Node* p = new Node();p->value = value;p->next = NULL;if(front == NULL){rear = p;}elsefront->next = p;front = p;}int Consume(){if(rear == NULL)return -1;size--;int result = rear->value;Node* temp = rear;rear = rear->next;delete temp;return result;}int getSize(){return size;}};int nProduce = 0;int nConsume = 0;pthread_mutex_t mutex;void* Producer(void* attr){Queue *queue = (Queue*)attr;while(nProduce < MAX){pthread_mutex_lock(&mutex);cout<<"Producer:"<<nProduce<<endl;queue->Produce(nProduce);nProduce++;pthread_mutex_unlock(&mutex);}}void* Consumer(void* attr){Queue* queue = (Queue*)attr;while(nConsume < MAX){pthread_mutex_lock(&mutex);int temp = queue->Consume();if(temp != -1){cout<<"Consumer:"<<temp<<endl;nConsume++;}pthread_mutex_unlock(&mutex);}}int main() {Queue *queue = new Queue();pthread_t producer_pthread, consumer_pthread;pthread_mutex_init(&mutex, NULL);pthread_create(&producer_pthread,NULL,Producer,queue);pthread_create(&consumer_pthread,NULL,Consumer,queue);pthread_join(producer_pthread,NULL);pthread_join(consumer_pthread,NULL);pthread_mutex_destroy(&mutex);return 0;}

Producer:0Producer:1Producer:2Producer:3Producer:4Producer:5Producer:6Producer:7Producer:8Producer:9Producer:10Producer:11Producer:12Producer:13Producer:14Producer:15Producer:16Producer:17Producer:18Producer:19Producer:20Producer:21Producer:22Producer:23Producer:24Producer:25Producer:26Producer:27Producer:28Producer:29Producer:30Consumer:0Consumer:1Producer:31Producer:32Consumer:2Consumer:3Producer:33Producer:34Producer:35Producer:36Producer:37Producer:38Producer:39Producer:40Producer:41Producer:42Producer:43Producer:44Producer:45Producer:46Producer:47Producer:48Producer:49Consumer:4Consumer:5Consumer:6Consumer:7Consumer:8Consumer:9Consumer:10Consumer:11Consumer:12Consumer:13Consumer:14Consumer:15Consumer:16Consumer:17Consumer:18Consumer:19Consumer:20Consumer:21Consumer:22Consumer:23Consumer:24Consumer:25Consumer:26Consumer:27Consumer:28Consumer:29Consumer:30Consumer:31Consumer:32Consumer:33Consumer:34Consumer:35Consumer:36Consumer:37Consumer:38Consumer:39Consumer:40Consumer:41Consumer:42Consumer:43Consumer:44Consumer:45Consumer:46Consumer:47Consumer:48Consumer:49