no image
DeadLock 탐지
DeadLock '교착 상태'라고도 하며, 두 개 이상의 작업이 서로 상대방의 작업이 끝나기 만을 기다리고 있기 때문에 결과적으로 아무것도 완료되지 못하는 상태 시스템적으로 한정된 자원을 여러 곳에서 사용하려고 할 때 발생 데드락이 발생할 수 있는 경우: Process 1과 Process2가 Resource 1, 2를 둘 다 얻어야 한다고 가정할 때, 서로 원하는 Resource가 상대 Process에게 할당되어 있기 때문에 두 프로세스가 무한정 기다리게 된다. 교착 상태의 조건 조건 설명 상호 배제 (Mutual exclusion) - 자원은 한 번에 하나의 프로세스만이 사용할 수 있어야 한다. - 프로세스들이 필요로 하는 자원에 대해 배타적인 통제권을 요구한다. - 상호 배제를 제거하는 것은 가장 확..
2023.02.07
no image
Reader-Writer Lock
전에 만들었던 코드에서 CoreGloabl을 조금 수정하였다. //CoreGloabl.h #pragma once extern class ThreadManager* GThreadManager; //CoreGloabl.cpp #include "pch.h" #include "CoreGlobal.h" #include "ThreadManager.h" ThreadManager* GThreadManager = nullptr; class CoreGlobal { public: CoreGlobal() { GThreadManager = new ThreadManager(); } ~CoreGlobal() { delete GThreadManager; } }GCoreGlobal; 이렇게 하면 CoreGloabl을 굳이 main 같..
2023.02.02
ThreadManager
프로젝트 파일 (앞으로 이 코드에 더 추가할 예정.) https://github.com/RuuNee/IOCP_Game_Server.git 스레드를 std::thread t1; 이런 식으로 만들어서 사용해도 문제가 될건 없지만, 나중에 가면 tls에도 굉장히 많은 데이터도 들어가게 될 것인데 이를 묶어서 관리해줄 코드를 만들어 보자. Types.h template using Atomic = std::atomic; using Mutex = std::mutex; using CondVar = std::condition_variable; using UniqueLock = std::unique_lock; using LockGuard = std::lock_guard; 우선 자주 사용하는 구조체와 클래스들을 재정의 해..
2023.02.01
Lock-Free Stack(3)
template class LockFreeStack { struct Node; struct CountedNodePtr { int32 externalCount = 0; Node* ptr = nullptr; }; struct Node { Node(const T& value) : data(make_shared(value)) {} shared_ptr data; atomic internalCount = 0; CountedNodePtr next; }; public: void Push(const T& value) { CountedNodePtr node; node.ptr = new Node(value); node.externalCount = 1; //[1] node.ptr->next = _head; while (_he..
2023.01.27
Lock-Free Stack(2)
template class LockFreeStack { struct Node { Node(const T& value) : data(value),next(nullptr) {} T data; Node* next; }; public: //1) 새 노드를 만들고 //2) 새 노드의 next = head //3) head = 새 노드 void Push(const T& value) { Node* node = new Node(value); node->next = _head; while (_head.compare_exchange_weak(node->next, node) == false) { } } //1) head 읽기 //2) head->next 읽기 //3) head = head->next //4) data 추출해..
2023.01.27
Lock-Free Stack (1)
lock기반의 스택과 큐를 만들어 보았는데 이번에는 lock을 사용하지 않는 버전으로 만들어 보자. (이를 lock free 프로그래밍이라 부른다고 한다.) template class LockFreeStack { struct Node { Node(const T& value) : data(value) {} T data; Node* next; }; public: //1) 새 노드를 만들고 //2) 새 노드의 next = head //3) head = 새 노드 void Push(const T& value) { Node* node = new Node(value); node->next = _head; /* if (_head == node->next) { _head = node; return true; } else..
2023.01.26
lock stack,queue
#pragma once #include template class LockStack { public: LockStack() {} LockStack(const LockStack&) = delete; LockStack& operator=(const LockStack&) = delete; void Push(T value) { lock_guard lock(_mutex); _stack.push(std::move(value)); _condVar.notify_one(); } bool TryPop(T& value) { lock_guard lock(_mutex); if (_stack.empty()) return false; value = std::move(_stack.top()); _stack.pop(); return ..
2023.01.26
no image
Thread Local Storage(TLS)
우리가 사용하던 스레드의 메모리 나타낸 그림이다. 그림에서 보듯이 Heap 영역과 데이터 영역은 공용으로 같이 활용하는 영역이다. 반면에 스택은 각자 따로 분리되어 데이터를 사용하게 된다. 그래서 Heap 영역 또는 데이터 영역에 자신이 사용하려는 데이터가 있을 경우 동시접근을 하기 위해(race condition 방지) lock을 잡아서 동기화를 해서 한번에 한 개의 스레드만 접근하도록 해주었다. TLS(Thread Local Stroage) 그런데 사실 위의 그림에는 숨겨진 녀석이 있는데 바로 TLS(Thread Local Storage)라는 녀석이다. 대충 스레드마다 가지고 있는 로컬 저장소라는 의미이다. 그래서 Heap 영역 또는 데이터 영역에 자신이 사용하려는 데이터가 있을 경우 동시접근을 하기..
2023.01.25
Future
동기와 비동기 동기 : 코드가 위에서 부터 아래로 내려오면서, 하나가 끝나면 다음 코드가 실행되는 방식 비동기 : 프로그램의 실행이, 한 갈래가 아니라 여러 갈래로 갈라져서 동시에 진행되는 것. std::future future는 미래에 실행이 완료될 것으로 예상되는 객체를 말한다. 따라서 아직 실행되지 않은 경우나, 실행 중이지만 아직 완료되지 않은 경우를 포함한다. future 객체에 요청한 값이 들어오기를 기다리는 동안 다른 연산을 수행할 수 있다. future를 사용하면 비동기 방식으로 실행한 함수의 결과물을 future 객체에서 get을 통해 가져올 수 있다. int64 Calculate() { int64 sum = 0; for (int32 i = 0; i < 100'000; i++) sum +..
2023.01.05