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

本文介绍了如何实现一个生产者消费者队列,使用面向对象的方法,包含生产和消费的线程操作。在g++环境下,利用POSIX兼容库和互斥量进行线程同步。然而,程序在某些情况下会出现死循环,经过分析发现是队列管理的错误,特别是当队列空时,导致front指针指向已释放内存,引发问题。修复后的Consume函数解决了这个问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

实现一个队列。
队列的应用场景为:

一个生产者线程将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 50

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


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值