목록C++ (54)
Coding Memo
C++20에서 추가된 Concepts의 기능인 requires에 대해서 간단히 정리해보자. requires는 C#에 비유하자면 where와 비슷한 키워드라고 생각할 수 있을 것 같다.where가 C#에서 제레릭 타입에 대한 조건을 지정하듯이,C++에서도 템플릿 타입에 대해 조건을 지정할 수 있다. Concepts 도입 전에는 SFINAE(Substitution Failure Is Not An Error)를 이용해, 템플릿 타입을 제약했었다. 그러나 C++20 이후에는, 템플릿에서 requires를 이용하여 타입에 대한 제약 조건을 쉽고 직관적으로 지정할 수 있다. 먼저 일반적인 코드를 확인해보자.struct A {};template T add(T a, T b){ return a + b;}int main(..
Windows 어플리케이션 개발 시, 하나의 어플리케이션의 실행만 허용해야할 때가 있을 것이다. 예를 들어, 게임에서 클라이언트 다중 실행을 막거나,서버에서 같은 프로그램이 동시에 실행되는 것을 방지하는 등이 있겠다. Windows에서 동일한 응용 프로그램을 여러 번 실행하는 것을 방지하기 위한 방법에는 어떤 것들이 있는지 알아보자. 1. Mutex 이용 멀티 스레드 환경에서 (하나의 응용 프로그램 내에서) 동기화를 위해 mutex를 활용하듯이, 커널에서도 mutex를 사용할 수 있다. 이 mutex는 커널 오브젝트 (kernel object)로, 하나의 프로세스만 해당 자원에 접근 할 수 있도록 할 수 있다.자세한 내용은 다음 글에!https://minttea25.tistory.com/168 Wind..
프로그램 내의 스레드 간 공유 자원에 대한 접근을 제한하는 것처럼 프로세스에서도 어떤 자원에 대해, 같은 응용 프로그램이 동시에 변경을 하거나, 작업을 하면 안되는 경우가 있다. 어떻게 방지 할 수 있을까? 여러 방법 중 하나로, Windows에서 제공하는 mutex를 활용하는 방법이 있다.HANDLE CreateMutexW( [in, optional] LPSECURITY_ATTRIBUTES lpMutexAttributes, [in] BOOL bInitialOwner, [in, optional] LPCWSTR lpName); HANDLE OpenMutexW( [in] DWORD dwDesiredAccess, [in] B..
싱글턴 디자인 패턴은 어플리케이션 전체에서 단 하나만 존재해야하는 인스턴스를 위한 패턴이다. 특정 인터페이스를 제공한다거나 동일한 데이터를 사용할 때 한번만 로드할 때 사용한다. 보통은 전역적으로 접근 가능한 인스턴스를 사용한다. 또, 어플리케이션 시작 시점에 인스턴스를 로드할지, 이후에 사용할 때 로드 할지 (Lazy Intialization) 잘 고려하면 될 것이다. 싱글턴 패턴 구현은 언어와 개발 환경에 따라 크게 달라지는 것 같다.인스턴스를 1개로 제한하는 방법에는 인스턴스 카운트를 관리하는 코드를 추가하거나, static 전역 변수를 두어 이 인스턴스를 반환하여 사용하는 메서드를 만들면 될 것이다.보통 후자의 방법이 많이 사용되는 것 같다. 먼저 구현하는 코드를 살펴보자. struct Singl..
Fisher-Yates Shuffle (피셔 예이스 셔플) 알고리즘은 랜덤 값을 이용해, 배열을 uniform하게 섞을 수 있는 알고리즘이다. 한번 순환 (1 iterator)로 셔플을 완성할 수 있다. 매우 간단하다. 랜덤하게 숫자 하나를 뽑고 그 값을 인덱스로 치환한다음 그 값과 현재 값을 swap한다.// Fisher-Yates Shuffle Algorithmvoid Shuffle(std::vector& arr){ int n = arr.size(); for (int i = n - 1; i > 0; i--) { int j = rand() % (i + 1); swap(arr[i], arr[j]); }} 하나 주의할 점은 랜덤 값을 얻는 함수로 rand()를 사용했기 때문에 시드를 설정 해줘야 한..
Dynamic Library (dll) - dllexport / dllimport (MSVC)__declspec(dllexport)와 __declspec(dllimport)는 MSVC(Microsoft Visaul C++) 컴파일러에서 사용하는 키워드이다. 동적 라이브러리(dynamic library)에서 클래스나 메서드, 변수를 내보내거나 가져올 때 사용된다.(보통 Windows에서 사용하고, GCC나 Clang에서는 __attribute__((visibility("default"))) 등을 사용) 간단히 말하면, 라이브러리에서 dll을 빌드할 때는 __declspec(dllexport) 키워드를 클래스 이름이나 메서드 원본 앞, 멤버 변수 앞 등에 붙여서 해당 내용을 외부에서 사용하도록 내보내겠다는 ..
문제 소켓이 연결이 되었음에도 불구하고, getpeername() 함수가 SOCKET_ERROR를 반환하고, WSAGetLastError() 값이 10057(WSAENOTCONN)이었다. 해당 소켓에 대해 WSASend 및 WSARecv는 정상적으로 작동하였고, getsockname또한 정상적으로 작동하였다. 해결 연결된 소켓에 대해 SO_UPDATE_CONNECT_CONTEXT 옵션을 설정해 주면 된다.이후 getpeername은 정상적으로 작동하고, remote endpoint의 주소와 포트 번호를 가져올 수 있다. 설명 SO_UPDATE_CONNECT_CONTEXT는 소켓이 연결 된 이후에, 소켓의 속성을 업데이트하는 옵션이다. 이 옵션은 ConnectEx, WSAConnectByList, WSA..
윈도우에서 지원하는 concurrent에 대한 자료구조 헤더가 있는데, 이들은 lock-free로 구현되어 있으니 이 쪽을 사용하는 것이 훨씬 더 도움이 될 수도 있겠다 ㅋㅋ std::mutex를 이용한 lock과 std::priority_queue를 사용하여 간단한 concurrent 우선순위 큐를 만들어보았다.기본적인 push 및 pop 외에, 지정된 조건에 따라 결과값을 반환하는 TryPop등의 함수도 포함했다.상황에 따라 필요할 수도 있기 때문이다. (예를 들어, top의 객체를 확인하고 이 객체가 어떤 조건이 맞을 경우에만 pop을 해야할 필요가 있을 때, top과 pop을 따로하면 atomic하게 실행시켜야되는 데, 이 과정에서 외부 lock을 걸어야 되기 때문이다.) 추가적으로, 이동연산자를..