C# 53

네트워크 기초 + 통신 모델

컴퓨터에서 네트워크를 통한 통신은 다음과 같이 이뤄지게 됩니다.그 이전에 컴퓨터가 네트워크 상에서 어떻게 구성되어 있는지 알고 있어야 합니다. 동일한 네트워크 주소를 갖고 있는 여러개의 컴퓨터 즉, 동일한 주소를 갖고 있는 단말기들은 하나의 스위치에서 관리됩니다.동일한 주소를 갖고 있는 단말기들의 통신은 스위치에서 수행하게 됩니다. 그러나 다른 주소를 갖고 있는 단말기들의 통신은 스위치가 아닌 라우터를 통해 이뤄지게 됩니다.서로 다른 주소의 단말기를 관리하는 스위치로부터 라우터가 통신을 진행하게 됩니다. 조금 더 이해하기 쉽게 사진을 하나 준비했습니다. 위와 같은 사진에서 단말기-a와 단말기-b의 통신은 스위치-Eng이 수행하게 됩니다. 그러나 단말기-a와 단말기-1이 통신하는 경우는 스위치-Eng과 스..

C# 2024.12.11

Thread Local Storage

자원이 여러 개 있고 스레드들이 자원에 접근하여 사용을 하는 경우가 있다고 생각해보겠습니다.자원마다 Lock을 걸게 되면 자원에 대한 원자성은 보장되지만, 하나의 자원에 대해 여러 스레드의 접근이 이뤄지면 대기가 길어져 처리가 늦춰지는 문제가 발생합니다.그리고 이런 경우 대기가 길어져 멀티 스레드의 장점을 살리지 못하고싱글 스레드보다도 효율적이지 못한 방식이 되어버립니다. 이런 상황에서 사용할 수 있는 것이 바로 Thread Local Storage 즉, TLS입니다.동적할당되는 데이터들을 위한 Heap 영역이나 전역 변수와 같은 공용 변수를 위한 Data 영역같은 경우 모든 스레드들이 같이 사용하는 영역입니다.그에 반해 지역변수같은 데이터를 위한 Stack 영역의 경우 스레드들이 각각 갖고 있습니다.T..

C# 2024.12.09

ReaderWriterLock 구현

이전에 설명한 적이 있는 ReaderWriterLock에 대해 간단하게 구현해보도록 하겠습니다.구현방식은 다음과 같습니다. int 형의 비어있는 플래그를 사용하여 ReaderLock과 WriterLock을 구현합니다.int는 4바이트 총 32비트로 구성되어 있으므로 다음과 같이 사용이 가능합니다.1비트 = 사용안함15비트 = WriteLock을 사용하여 자원을 점유하는 스레드 기록16비트 = ReadLock을 사용하여 자원을 점유하는 스레드 기록그리고 만들어지는 Lock은 스핀락을 사용하여 만들고 스핀락의 대기횟수를 제한하겠습니다.그리고 Lock 안에서 yield를 통해 실행가능한 스레드에게 자원의 점유를 넘겨주겠습니다.마지막으로 WriterLock의 경우 Lock 안에서 재귀적으로 다른 Lock을 설정..

C# 2024.12.09

Lock 구현 훑어내리기 + ReaderWriterLock 기초

1) 일반적인 lock가장 먼저 알아볼 Lock 구현은 일반적인 lock 키워드를 통한 lock 입니다.사용할 수 있는 방식은 다음과 같습니다.static object _lock = new object();static void Main(string[] args){ lock (_lock) { }} object 타입의 _lock 변수를 사용하며lock의 경우 내부적으로 Monitor가 동작합니다. 2) SpinLock다음으로는 SpinLock을 통한 Lock 구현입니다.SpinLock을 통해 Lock은 무한히 대기하며 자원의 점유가 풀리기를 기다립니다.사용할 수 있는 방식은 다음과 같습니다.class Program{ // C# API - SpinLock : 이때의 SpinLoc..

C# 2024.12.04

Event를 통한 Lock 구현

이번에는 Lock을 구현하는 3가지 방법 중에서 Event를 통해 Lock을 구현하는 방법을 알아보겠습니다.Event를 통해 Lock을 구현하는 방식은 2가지가 존재하는데,자동으로 동작하는 AutoResetEvent와 수동으로 조작해야 하는 ManualResetEvent가 존재합니다. 1) AutoResetEvent제일 먼저 AutoResetEvent를 통해 Lock을 구현해보도록 하겠습니다.코드는 다음과 같습니다.class Lock{ // AutoResetEvent의 true 또는 false 값에 따라 해당 이벤트가 사용가능한 상태를 의미함 AutoResetEvent _available = new AutoResetEvent(true); public void Acquire() { ..

C# 2024.12.04

Context Switching

멀티 스레드를 구현하는 3가지 방식 중에서 Context Switching에 대해 알아보겠습니다.Context Switching은 다른 스레드가 자원을 점유하는 동안대기하지 않고 하던 일을 마저 하다가 일정 시간 후에 자원 점유 여부를 확인합니다. 이러한 Context Switching을 구현하는 방법은 총 3가지로 구분할 수 있습니다.1) Thread.Sleep(n)위와 같이 사용할 수 있으며 이때 n은 0이 아닌 수를 의미합니다.스레드는 자신의 작업을 계속 수행하다가 n초 후에 자원이 점유되었는지 확인합니다.자원이 점유되어있다면 자신의 작업을 계속 진행하고점유되어 있지 않다면 기존의 작업을 RAM에 저장한 뒤 해당 자원의 작업을 수행하게 됩니다. 2) Thread.Sleep(0)Thread.Sleep..

C# 2024.12.04

SpinLock

락을 구현하는 3가지 방식 중 하나인 스핀락에 대해 알아보고 이를 예제로 살펴보겠습니다.스핀락은 자원에 접근하기 위해 무한히 대기하여 락을 구현하는 방식입니다.따라서 이론적으로 다음과 같이 구현할 수 있을 것입니다. 1) 첫 번째 시도class SpinLock{ volatile bool _key = false; public void Accquire() { // 잠금이 풀릴때까지 대기 while (_key) { } // 잠금 설정 _key = true; } public void Release() { // 잠금 해제 _key = false; }}class Program{ static in..

C# 2024.12.04

DeadLock과 Lock구현

이전 포스트에서 DeadLock에 대해 한번 언급을 했었습니다.DeadLock은 멀티 스레드 환경에서스레드가 자원을 계속 점유하여 다른 스레드가 이 자원을 사용하기 위해 대기하는 문제를 말합니다. 이번 포스트에서는 멀티 스레드 환경에서 DeadLock이 발생하는 예시를 한번 살펴보고DeadLock을 어떻게 해결해야 하는지 한번 고민해보도록 하겠습니다. 1) 예시 코드class SessionManager{ static object _key = new object(); public static void Test() { lock (_key) { ClientManager.TestClient(); } } public static..

C# 2024.12.02

Lock 기초

이전에 알아본 InterLocked는 멀티 스레드 환경에서 사용할 수 있는 중요한 요소 중 하나입니다.그러나 InterLocked가 가진 치명적인 단점은 정수형 변수만 다룰 수 있다는 점입니다.따라서 이번에는 다른 방식으로 멀티스레드 환경을 만들어보겠습니다. 멀티스레드 환경에서는 단순히 읽어오는 것은 문제가 되지는 않지만, 쓰기 시작하면서 문제가 발생하기 시작합니다.그리고 이런 식으로 문제가 발생하는 코드 영역을 Critical Section 한국어로 임계영역이라고 합니다. 1) Monitor 클래스를 통한 임계영역 제한이럴 때 사용가능한 클래스가 바로 Monitor 클래스이고,Monitor 클래스의 함수 Enter와 Exit입니다.다음의 사용예제를 보겠습니다.  class Program { st..

C# 2024.12.02

Interlocked

멀티스레드 환경은 싱글스레드와 다르게 신경써야 하는 것이 매우 많습니다.그 중에서도 전역 변수같은 공용으로 사용하는 변수에 대해서 알아보겠습니다. 아래의 코드를 한번 살펴보겠습니다.class Program{ static int number = 0; static void Thread_1() { for (int i = 0; i  일반적으로 생각하는 결과는 0일 것입니다.100000000번동안 1을 더하고, 100000000번동안 1을 빼므로 값은 0이라 생각되지만, 결과는 다음과 같습니다. 위와 같은 결과가 발생한 이유는 공용변수 Task에 대한 원자성이 보장받지 못하기 때문입니다.간단하게 말하자면 원자성이 보장받는다는 것은해당 데이터에 수행하는 작업이 동시에 발생할 수 있는 작..

C# 2024.11.27