【面试练习题】C++ 使用多线程实现交替打印两个数组 + PV操作

互斥锁的版本:

#include 
#include 
#include 
#include 
using namespace std;

std::mutex data_mutex;
int flag = 0;

void printA(int* a, int size) {
	for (int i = 0; i < size; ) {
		data_mutex.lock();
		if (flag == 0) {
			cout << a[i] << endl;
			flag = 1;
			++i;
		}
		data_mutex.unlock();
	}
}

void printB(char* b, int size) {
	for (int i = 0; i < size; ) {
		data_mutex.lock();
		if (flag == 1) {
			cout << b[i] << endl;
			flag = 0;
			++i;
		}
		data_mutex.unlock();
	}
}

int main()
{
	int a[4] = { 1, 2, 3, 4 };
	char b[4] = { 'a', 'b', 'c', 'd' };
	std::thread tA(&printA, a, 4);
	std::thread tB(&printB, b, 4);
	tA.join();
	tB.join();

	return 0;
}

使用互斥锁+条件变量的版本:

#include 
#include 
#include 
#include 
using namespace std;

std::mutex data_mutex;
std::condition_variable data_var;
int flag = 0;

void printA(int* a, int size) {
	for (int i = 0; i < size; i++) {
		
		std::unique_lock lck(data_mutex);
		data_var.wait(lck, [] {return flag == 0; });
		
		cout << a[i] << endl;
		flag = 1;
		
		data_var.notify_all();
		
	}
}

void printB(char* b, int size) {
	for (int i = 0; i < size; ++i) {
		std::unique_lock lck(data_mutex);
		data_var.wait(lck, [] {return flag == 1; });
		
		cout << b[i] << endl;
		flag = 0;
		
		data_var.notify_all();
	}
}

int main()
{
	int a[4] = { 1, 2, 3, 4 };
	char b[4] = { 'a', 'b', 'c', 'd' };
	std::thread tA(&printA, a, 4);
	std::thread tB(&printB, b, 4);
	tA.join();
	tB.join();

	return 0;
}

PV操作

#include 
#include 
#include 
#include 

using namespace std;
const int PRONUM = 10; // 生产者总个数
const int CONSUNUM = 5; // 消费者总个数
const int SUM = 30; // 需要的商品总个数
const int CAP = 20; // 缓冲区长度
vector storage(CAP); // 缓冲区
int cnt = 0; // 仓库内货物计数器,判断是全满还是全空
mutex mutex_storage;// 保护缓冲区的锁
condition_variable con_emp;
condition_variable con_full;
static int has_consumed = 0; // 总共消费的
static int has_produced = 0; // 总共生产的

class Pointer {
private:
	int p;
public:
	Pointer() : p(0){}
	int& operator++() {
		p++;
		if (p == CAP) {
			p = 0;
		}
		return p;
	}
	int& operator++(int) {
		return ++(*this);
	}
	int& operator*() {
		return p;
	}
};

Pointer p_em; // 指向第一个空的位置
Pointer p_full; // 指向第一个满的位置

// 生产者线程
void produce() {
	do{
		unique_lock lck(mutex_storage);
		con_emp.wait(lck, []() {return cnt != CAP; });
		storage[*p_em] = has_produced;
		cnt++;
		cout << this_thread::get_id() << "生产了" << storage[*p_em] << "号, 目前有:" << cnt << "个" << endl;
		this_thread::sleep_for(std::chrono::milliseconds(100));
		p_em++;
		has_produced++;
		con_full.notify_one();
	} while (has_produced <= SUM);
}

void consume() {
	do {
		unique_lock lck(mutex_storage);
		con_full.wait(lck, []() {return cnt != 0; });
		cnt--;
		cout << this_thread::get_id() << "消费了" << storage[*p_full] << "号, 目前有:" << cnt << "个" << endl;
		this_thread::sleep_for(std::chrono::milliseconds(500));
		p_full++;
		has_consumed++;
		con_emp.notify_one();
	} while (has_consumed <= SUM);
}

int main()
{
	vector vec_p;
	vector vec_c;
	for (int i = 0; i < PRONUM; ++i) {
		vec_p.push_back(thread(produce));
	}
	for (int i = 0; i < CONSUNUM; ++i) {
		vec_c.push_back(thread(consume));
	}
	for (int i = 0; i < PRONUM; ++i) {
		vec_p[i].join();
	}
	for (int i = 0; i < CONSUNUM; ++i) {
		vec_c[i].join();
	}
	return 0;
}

 

你可能感兴趣的:(c++学习笔记,笔试题)