목록Language (73)
Coding Memo
공통적으로 Microsoft에서 개발한 프레임워크로, 다양한 종류의 어플리케이션을 개발하고 실행하는 기술을 제공해준다. 개발된 순서 .NET Framework -> .NET Core -> .NET (5.0, 6.0, 7.0 ...) .NET Framework 주로 Windows에서 실행되는 프로그램을 개발하기 위해 사용되는 프레임 워크이다. 초기에 개발되고 사용되었고 .NET Framework의 한계점과 개선을 위해서 이후에는 .NET Core가 등장하였다. 1. Windows Desktop, ASP.NET 웹, Windows 서비스 등의 개발에 활용된다. 2. CLR (Common Language Runtime): Java의 JVM과 비슷한 역할로, .NET Framework의 실행 환경으로, 코드 실..
Serilog는 멀티스레드 환경에서 별도 lock 컨트롤 없어도 괜찮은지 확인해보려고 한다. (기본적으로 Serilog는 thread-safe 하다고 한다.) 10개의 쓰레드 생성 각 쓰레드 마다 1000개의 로그 기록 => 총 n값이 10000까지 출력이 되어야 하고 n 값이 중복되서는 안된다. 다음 함수를 쓰레드로 실행시킬 것이다. n은 static으로 선언해서 별도의 lock 처리 없이 Information (및 Verbose, Debug, Error, Fatal)에서 ++n이 잘 실행되는지도 확인해보겠다. 추가적으로 운좋게(?) 경합이 일어나지 않아 예상대로 출력될 수도 있으니 3번씩은 실행시켜보았다. static int n = 0; static void Thread1() { for (int i ..
lock과 spinlock은 모두 멀티스레드 환경에서 공유 자원을 컨트롤하기 위한 동기화 메커니즘이다. 한 스레드가 접근 중일 때는 다른 스레드들은 대기하게 된다. 그렇다면 각각 어떤 특징이 있고, 어떤 상황에서 둘 중 무엇을 사용해야 더 성능면에서 유리하게 사용할 수 있을지 알아보았다. 대기 방식 - lock: 락을 얻을 때까지 대기를 하고, 대기하는 동안 CPU 자원을 사용하지 않음 - spinlock: busy-waiting 방식으로 다른 쓰레드가 락을 해제할 때까지 계속 루프를 돌면서 기다리고 이 대기 동안에 CPU를 계속 사용함 이 외에는 크게 의미 있는 차이가 없는 것 같다. lock 방식은 CPU 자원을 많이 사용하지 않지만 lock을 얻고 해제하는데 다소 자원이 들어갈 수 있다. 반면에 s..
멀티 쓰레드 환경에서는 여러 쓰레드가 한번에 어떤 공유 자원(전역 변수, 맴버 변수 등등)에 접근하고 수정하려고 하면 매우 큰 문제가 발생할 수도 있다. 아래 코드의 실행 결과를 예상해보자. class Program { static int n = 0; static void Thread1() { for (int i=0; i
C++에서 상수를 정의하는 방법으로 2가지가 있다. 첫 번째로, define을 이용하여 매크로로 상수를 정의하는 방법이 있고, 두 번째로는 constexpr을 이용하여 상수를 정의하는 방법이 있다. #define PI 3.141592 constexpr double PI = 3.141592; 두 방법의 특징과 차이점을 보고 무엇을 사용하면 더 좋을지 확인해보자. define define은 전처리기(preprocessor) 지시자로, C++의 전처리기를 통해 상수를 정의하는 방법이다. 이는 매크로를 이용하는데, 매크로는 컴파일 전에 사용된 매크로값이 텍스트 치환을 통해 해당 정의 내용으로 그대로 바뀐다. (말 그대로 매크로 값에 정의했던 내용이 그대로 들어간다. 단순히 텍스트 치환 기능이다.) define의..
vector, deque, set, map, stack, queue, priority_queue 등의 컨테이너와 자료구조에서 자주 사용하는 함수들을 간단하게 요약하였다. 먼저, 간단하게 표현하기 위해서... 편의상 템플릿 타입과 컨테이너 사이즈 타입(size_t)은 int 형으로 하였다. 템플릿 타입 명시 를 생략하였다. const를 생략했고 각 컨테이너의 iterator는 간단하게 iterator로만 표현했다. 진짜 진짜 주요한 함수만 확인해보려면 스크롤을 맨 아래로 내리자! 참조: https://en.cppreference.com/w/cpp/container vector Sequence Container로 요소에 대해 순차적으로 접근 할 수 있다. (forward, backward 둘 다 순회 가능)..
흐름 제어란? 발신자가 수신자가 처리할 수 있는 것보다 더 빨리, 많이 데이터를 보낼 경우에 수신자는 일부 데이터(패킷)에 대해 삭제가 되거나 손실이 발생 할 수 있다. 이 문제를 방지하기 위해 TCP 연결에서는 흐름제어를 사용한다. 흐름제어(flow-control)는 수신자의 상태를 보고 전송을 제어하여 데이터의 손실이나 정체 없이 효율적이고 안정적으로 통신을 가능하게 한다. 예를 들어, 수신자가 100바이트의 버퍼를 가지고 있는데, 발신자가 150바이트의 데이터를 보냈다고 가정하자. TCP 연결에서 발신자는 수신자가 처리 할 수 있는 데이터의 양 (Sliding Window)을 미리 정한다. 따라서 발신자는 먼저 100바이트를 송신하고, 수신자가 먼저 100바이트를 받고 처리 후, 발신자에게 추가 데..
[요약] SocketAsyncEventArgs.BufferList을 통해 데이터를 전송 할 때, 반드시 새로운 리스트를 만들고 바이트 데이터를 그 리스트에 추가(Add)를 한 후에 그 리스트를 SocketAsyncEventArgs.BufferList에 직접 할당해야만 한다!! (이 관련 내용은 공식적으로 문서화 되어있지 않다고 한다.) 1. 리스트 생성 (IList) 2. 1에서 생성한 리스트에 아이템 추가(Add) 3. SocketAsyncEventArgs.BufferList에 1에서 생성한 리스트 직접 할당 ***SocketAsyncEventArgs.BufferList에 직접 아이템 Add 하지 말자.*** Why? BufferList의 Setter 호출 시, 기존 리스트에 있는 버퍼만 사용하기 때문..