#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 |