【C++多线程】生产者消费者模型

文章目录

      • 一、题目要求
      • 二、解答
      • 三、题目要求
      • 四、解答
        • (1)行锁
        • (2)表锁

一、题目要求

生产者消费者模型:在多线程下生产0~100个数,生产者线程1生产20个数据后,消费者线程1进行消费输出。

二、解答

使用到的技术:互斥锁、条件变量、多线程、双端队列

#if 1
#include
#include
#include
#include
using namespace std;

mutex mtx;
std::condition_variable cv;

class Queue
{
public:
	//生产数据: index是生产者编号,val是生产的结果
	void PushData(int index, int val)
	{
		unique_lock<mutex> lock(mtx);
		//size == 20
		cv.wait(lock, [this]()->bool {return qu.size() != 20; });
		qu.push_back(val);
		cv.notify_all();
		cout << "Producer:" << index << " " << "val:" << val << endl;
	}
	//消费数据: index是消费者编号
	void PopData(int index)
	{
		unique_lock<mutex> lock(mtx);
		//!qu空 ->真 , 继续执行
		cv.wait(lock, [this]()->bool {return !qu.empty(); });
		int val = qu.front();
		qu.pop_front();
		cv.notify_all();
		cout << "Customer:" << index << " " << "val:" << val << endl;
	}
private:
	deque<int> qu;
};
void Producer(Queue& qu, int index)
{
	for (int i = 0; i < 100; ++i)
	{
		qu.PushData(index, i);
	}
}
void Customer(Queue& qu, int index)
{
	for (int i = 0; i < 100; ++i)
	{
		qu.PopData(index);
	}
}

int main()
{
	Queue qu;
	thread tha(Producer, std::ref(qu), 1);
	thread thb(Customer, std::ref(qu), 1);

	//thread thc(Producer, std::ref(qu), 2);
	//thread thd(Customer, std::ref(qu), 2);

	tha.join();
	thb.join();
	//thc.join();
	//thd.join();
	return 0;
}
#endif

【C++多线程】生产者消费者模型_第1张图片

三、题目要求

实现一个循环队列,生产者线程生产0~100, 每次最多生产8个,然后消费者线程进行输出使用。

根据锁的粒度分为:

  • 行锁:并发性强,锁开销较大
  • 表锁:并发性弱,锁开销较小

四、解答

(1)行锁
#if 1
#include
#define MAXSIZE 8
#include
#include

using namespace std;
template<class T>
class Queue
{
public:
	Queue() 
		:data(new T[MAXSIZE]), maxsize(MAXSIZE), front(0), rear(0), size(0)
	{}
	~Queue()
	{
		if (nullptr != data)
		{
			delete data;
		}
		maxsize = -1;
		front = -1;
		rear = -1;
		size = -1;
	}
	bool Capacity()const { return maxsize; }
	bool Size()const { return size; }
	bool Empty()const { return size == 0; }
	bool Full()const { return size == maxsize; }
	bool Push_back(T& val)
	{
		if (Full()) return false;
		data[rear] = val;
		rear = (rear + 1) % maxsize;
		++size;
		return true;
	}
	bool Pop_front(T& val)
	{
		if (Empty()) return false;
		val = data[front];
		front = (front + 1) % maxsize;
		--size;
		return true;
	}

private:
	T* data;
	int maxsize;
	int size;
	int front;
	int rear;
};
Queue<int> qu;
std::mutex mtx;
std::condition_variable cv;
int number = 0;
void Producer(int index)
{
	for (int i = number; i < 100; ++i)
	{
		//行锁
		unique_lock<mutex> lock(mtx);
		//当qu不满 为真,继续执行
		cv.wait(lock, []()->bool {return !qu.Full(); });
		//
		qu.Push_back(i);
		cv.notify_all();
		cout << "Producer:" << index <<" "<< "val:" << i << endl;
		std::this_thread::sleep_for(std::chrono::milliseconds(100));
	}
}
void Customer(int index)
{
	for (int i = number; i < 100; ++i)
	{
		//行锁
		unique_lock<mutex> lock(mtx);
		//当qu不空 为真,继续执行
		cv.wait(lock, []()->bool {return !qu.Empty(); });
		//
		int val = 0;
		qu.Pop_front(val);
		cv.notify_all();
		cout << "Customer:" << index << " " << "val:" << val << endl;
	}
}
int main()
{
	thread tha(Producer, 1);
	thread thb(Customer, 1);
	tha.join();
	thb.join();
	return 0;
}

#endif

【C++多线程】生产者消费者模型_第2张图片

(2)表锁
#if 1
#include
#define MAXSIZE 8
#include
#include

using namespace std;
template<class T>
class Queue
{
public:
	Queue() 
		:data(new T[MAXSIZE]), maxsize(MAXSIZE), front(0), rear(0), size(0)
	{}
	~Queue()
	{
		if (nullptr != data)
		{
			delete data;
		}
		maxsize = -1;
		front = -1;
		rear = -1;
		size = -1;
	}
	bool Capacity()const { return maxsize; }
	bool Size()const { return size; }
	bool Empty()const { return size == 0; }
	bool Full()const { return size == maxsize; }
	bool Push_back(T& val)
	{
		if (Full()) return false;
		data[rear] = val;
		rear = (rear + 1) % maxsize;
		++size;
		return true;
	}
	bool Pop_front(T& val)
	{
		if (Empty()) return false;
		val = data[front];
		front = (front + 1) % maxsize;
		--size;
		return true;
	}

private:
	T* data;
	int maxsize;
	int size;
	int front;
	int rear;
};


Queue<int> qu;
std::mutex mtx;
std::condition_variable cv;
int number = 0;
void Producer(int index)
{
	unique_lock<mutex> lock(mtx);
	for (int i = number; i < 100; ++i)
	{
		//当qu不满 为真,继续执行
		cv.wait(lock, []()->bool {return !qu.Full(); });
		qu.Push_back(i);
		cv.notify_all();
		cout << "Producer:" << index <<" "<< "val:" << i << endl;
		//std::this_thread::sleep_for(std::chrono::milliseconds(100));
	}
}
void Customer(int index)
{
	unique_lock<mutex> lock(mtx);
	for (int i = number; i < 100; ++i)
	{
		//当qu不空 为真,继续执行
		cv.wait(lock, []()->bool {return !qu.Empty(); });
		int val = 0;
		qu.Pop_front(val);
		cv.notify_all();
		cout << "Customer:" << index << " " << "val:" << val << endl;
	}
}
int main()
{
	thread tha(Producer, 1);
	thread thb(Customer, 1);
	tha.join();
	thb.join();
	return 0;
}

【C++多线程】生产者消费者模型_第3张图片

你可能感兴趣的:(C++,c++,多线程,互斥锁,生产者消费者,条件变量)