#pragma once

#include <mutex>

template<typename T>
class LockQueue
{
public:
	LockQueue() = default;

	LockQueue(const LockQueue&) = delete;

	LockQueue& operator=(const LockQueue&) = delete;

	void push(T value)
	{
		lock_guard<mutex> lock(_mutex);
		_q.push(std::move(value));
		_conVar.notify_one();

	}
	
	bool tryPop(T& value)
	{
		lock_guard<mutex> lock(_mutex);
		if (_q.empty())
		{
			return false;
		}
		value = std::move(_q.front());
		_q.pop();
		return true;
	}


	//pop 할 데이터가 없을때 대기하다가 pop 할 데이터가 생기면 그때 pop하고 끝내는 함수
	void waitPop(T& value)
	{
		unique_lock<mutex> lock(_mutex);

		// stack 이 비어있지 않다면(false) == false => true
		// stack 이 비어 있다면 (true) == false => false  , 조건이 만족하지 않으면 lock 을 풀고 sleep 하게 된다
		_conVar.wait(lock, [this] { return _q.empty() == false; });
		value = std::move(_q.front());
		_q.pop();

	}

private:
	mutex _mutex;
	queue<T> _q;
	condition_variable _conVar;
};

 

#include "pch.h"
#include <iostream>
#include <thread>	
#include <mutex>
#include <chrono>
#include <future>
#include "windows.h"
#include "ConcurrentStack.h"
#include "ConcurrentQueue.h"

using namespace std;

//LockStack<int> st;
LockQueue<int> q;

void push()
{
	int i = 0;
	while (true)
	{
		q.push(i++);
		this_thread::sleep_for(10ms);
	}
	
}


void pop()
{
	while (true)
	{
		int popData = 0;
// 		if (q.tryPop(popData))
// 		{
// 			cout << popData << endl;
// 		}
		
		q.waitPop(popData);
		cout << popData << endl;

	}
}



int main()
{
	thread t1(push);
	thread t2(pop);
	t1.join();
	t2.join();

	return 0;
}

 

 

원리와 설명 실행결과는  (https://3dmpengines.tistory.com/2207) 이 글과 유사하다

단지 Queue  로 바꾼것일 뿐

반응형

'운영체제 & 병렬처리 > Multithread' 카테고리의 다른 글

LockFree - Stack (2) - 삭제 처리  (0) 2022.09.21
LockFree - Stack (1)  (0) 2022.09.15
Lock base Stack  (0) 2022.09.14
TLS(Thread Local Storage) : thread_local  (0) 2022.09.14
Sequential consistency (순차 일관성)  (0) 2022.09.13

+ Recent posts