언어/C# 46

C# async/await

개념 async/await 메서드는 비동기 함수라고도 불린다. 기존에 존재하던 Task의 장점을 살려 개발자가 좀 더 쉽게 비동기 작업을 수행할 수 있는 프로그래밍 만들고자 하여 탄생한 것이 바로 async/await 되시겠다. await 연산자는 피연산자가 나타내는 비동기 작업이 완료될 때까지 수행을 중지한다. 그리고 await연산자를 포함한 메서드에 async를 붙여 컴파일러가 해당 함수가 비동기 함수임을 알 수 있게 한다. static async void SomeMethod() { await Task.Run(() => { SomeHeavyWork(); //시간이 좀 걸리는 메서드 }); //Task가 끝난 뒤에야 아래 코드가 시작된다. Console.WriteLine("SomeHeavyWork En..

언어/C# 2022.06.12

스레드 동기화 - 기타 (이중 확인 락, 조건 변수, 컬렉션)

2022.05.29 - [언어/C#] - 복합 스레드 동기화 요소 복합 스레드 동기화 요소 2022.05.09 - [언어/C#] - 단순동기화3 - 커널 모드 동기화 단순동기화3 - 커널 모드 동기화 2022.05.06 - [언어/C#] - 단순동기화2 (유저 모드 동기화 요소) 커널 모드 동기화 요소 커널 모드 동기화 요소는 tsyang.tistory.com 이중 확인 락 기법 늦은 초기화(Lazy initialization)를 이용해 싱글톤 객체를 생성할 때, 다수의 스레드가 동시에 싱글톤 객체를 요청한다면 싱글톤 객체가 여러 번 생성될 수 있다. 따라서 스레드 동기화를 통해 싱글톤 객체가 단 한 번만 생성되도록 해줘야 하는데 이때 자주 사용되는 기법이 이중 확인 락(double-check locki..

언어/C# 2022.06.05

복합 스레드 동기화 요소

2022.05.09 - [언어/C#] - 단순동기화3 - 커널 모드 동기화 단순동기화3 - 커널 모드 동기화 2022.05.06 - [언어/C#] - 단순동기화2 (유저 모드 동기화 요소) 커널 모드 동기화 요소 커널 모드 동기화 요소는 유저 모드 동기화 요소에 비해서 상당히 느리다. 왜냐? 커널 모드 동기화 요소가 운영 tsyang.tistory.com 앞에서 유저모드 동기화, 커널 모드 동기화에 대해 다뤘다. 이 둘을 잘 섞은 복합 스레드 동기화 요소에 대해 알아보겠다. (제프리 리쳐가 만든 용어인듯?) 복합 스레드 동기화 요소 얘는 스레드들이 경쟁 상태가 아닐 때에는 유저 모드 동기화 요소를 써서 성능상의 장점을 취하고, 다수의 스레드가 경쟁 상태일 경우 커널 모드 동기화 요소를 써서 스피닝이 발생..

언어/C# 2022.05.29

단순동기화3 - 커널 모드 동기화

2022.05.06 - [언어/C#] - 단순동기화2 (유저 모드 동기화 요소) 커널 모드 동기화 요소 커널 모드 동기화 요소는 유저 모드 동기화 요소에 비해서 상당히 느리다. 왜냐? 커널 모드 동기화 요소가 운영체제에게 스레드 간의 동기화를 요청해서 그렇다. 또한 각각의 메서드들은 커널 객체를 이용하게 되고 이로 인해 스레드가 관리 코드 -> 네이티브 유저 모드 -> 네이티브 커널 모드 (돌아올 때도 역순으로 반복함) 위와 같은 전환을 일으켜 CPU 시간을 엄청나게 소비하기 때문이기도 하다. 그래도 커널 모드 동기화 요소를 쓰는 이유가 있다. 리소스에 대한 경쟁 상태를 확인할 수 있다. 스레드가 CPU를 낭비하지 않도록 한다. 네이티브 스레드와 관리 스레드 사이에서도 동기화를 할 수 있다. 동일 컴퓨터..

언어/C# 2022.05.09

단순동기화2 - 유저 모드 동기화

2022.05.01 - [언어/C#] - CLR 단순 동기화1 CLR 단순 동기화1 스레드 동기화 스레드 동기화는 일반적으로 다수의 스레드가 공유 데이터에 '동시에' 접근하는 경우에도 데이터가 손상되는 것을 막기 위해서 사용된다. 그러나 스레드 동기화는 많은 문제를 tsyang.tistory.com 유저 모드 동기화 요소 CLR은 bool, byte, short, int, float, 참조 타입의 변수에 대해서는 원자적(atomic)으로 값을 읽고 쓸 수 있음을 보장한다. 이게 뭔말이냐면 int x = 0; x = 0x01234567; x 변수가 0x00000000에서 0x01234567로 한 번에 번경된다는 말이다. 즉, 변경 중인 상태의 값을 얻어올 가능성이 없다는 말이다. 엥.. 그럼 아닌 경우도 ..

언어/C# 2022.05.06

CLR 단순 동기화1

스레드 동기화 스레드 동기화는 일반적으로 다수의 스레드가 공유 데이터에 '동시에' 접근하는 경우에도 데이터가 손상되는 것을 막기 위해서 사용된다. 그러나 스레드 동기화는 많은 문제를 가지고 있다. 우선 오류를 발생시킬 가능성이 높다. 왜냐? 코드를 작성할 때 여러 스레드에서 동시에 접근할 수 있는 데이터들을 모두 확인한 후, 스레드 동기화 락을 데이터 접근 부분에 모두 적용해야 한다. 만약 락을 한 군데라도 빠트리면 오류가 발생한다. 테스트도 매우 힘들다. 유일한 테스트는 그냥 여러번 실행시켜 본뒤 문제가 발생하기 않길 비는 수밖에... 그리고 이런 테스트는 여러 개의 CPU를 가진 컴퓨터에서 해보는게 좋다. 왜냐? 그래야 여러 개의 스레드가 동시에 리소스에 접근할 가능성이 높기 때문이다. 성능이 떨어지..

언어/C# 2022.05.01

CLR 스레딩3 - 태스크(Task)

2022.04.17 - [언어/C#] - CLR 스레드 단순 계산 작업 태스크 앞선 글에서 계산 중심의 비동기 작업을 주행하기 위해 ThreadPool 의 QueueUserWorkItem을 호출하는 방식을 소개헀다. 그러나 이 방법은 작업 완료 시점과 작업 수행의 결과를 얻을 수 있는 방법을 제공하지 않고 있다는 한계가 있다. 그래서 생긴게 태스크(tasks) 라는 개념이다. //ThreadPool을 이용한 방식 ThreadPool.QueueUserWorkItem(obj => Sum(1000)); //Task를 이용한 방식1 var task = new Task(() => Sum(1000)); task.Start(); //Task를 이용한 방식2 Task.Run(() => Sum(1000)); 태스크의 결..

언어/C# 2022.04.24

CLR 스레딩2 단순 계산 작업

2022.04.10 - [언어/C#] - CLR 스레드 기본 CLR 스레드 기본 윈도우 스레드 도입 응용 프로그램의 인스턴스는 '프로세스' 라고 부르는 공간 내에서 수행된다. 개별 프로세스는 자신만의 가상 주소 공간을 가지고 있어서 다른 프로세스가 자신의 코드나 데 tsyang.tistory.com CLR의 스레드에 대해 깊게 판다기 보다는 설계 아이디어에 초점을 맞춤 스레드 풀 이전 글에서 언급하였듯, 스레드를 생성하고 파괴하는 일은 상당한 시간을 소비한다. 또한 스레드를 과도하게 생성하면 잦은 컨텍스트 스위칭이 발생하여 성능에 악영향을 미친다. (+ 메모리 차지는 덤) 이런 상황을 위해 CLR은 고유의 스레드 풀을 관리하는 코드를 가지고 있다. 스레드풀은 CLR별로 하나씩 생성된다. CLR이 초기화 ..

언어/C# 2022.04.17

CLR 스레딩1 기본

윈도우 스레드 도입 응용 프로그램의 인스턴스는 '프로세스' 라고 부르는 공간 내에서 수행된다. 개별 프로세스는 자신만의 가상 주소 공간을 가지고 있어서 다른 프로세스가 자신의 코드나 데이터에 접근할 수 없다. 그러나 만약 한 응용프로그램이 무한 루프에 빠졌다면? 그리고 CPU가 하나밖에 없다면? 이렇게 되면 다른 코드나 사용자의 요청에 응답할 수 없는 상태가 되어버린다. 이러한 문제를 해결하기 위해 만들어 진 것이 '스레드'이다. 스레드는 CPU를 가상화 하기 위한 윈도우 운영체제의 개념이다. 스레드는 비용이 있지만 운영체제의 응답성이 좋아지게 하는 효과가 있다. 스레드의 비용 모든 스레드는 다음의 비용을 하나씩은 가진다. 스레드 커널 객체 : OS는 개별 스레드별로 고유의 데이터 구조체를 할당화하고 초..

언어/C# 2022.04.10

런타임 Serialization - 1

개요 serialization(직렬화) : 객체나 객체 그래프를 바이트 스트림으로 변환하는 과정 deserialization(역직렬화) : 바이트 스트림을 다시 연결된 객체 그래프로 되돌리는 과정 이런 직렬화와 역직렬화는 다음과 같은 기능을 한다. 응용프로그램의 상태(=객체 그래프)를 파일이나 DB에 쉽게 저장하고 다시 불러올 수 있다. 객체들을 시스템의 클립보드에 복사/붙여넣기 할 수 있다. 사용자가 객체를 수정하는 동안 원본 객체들을 백업하는 용도로 쓸 수 있다. 객체를 네트워크를 통해 전송한다. 객체를 바이트 스트림으로 메모리에 serialize하면 데이터의 암호화나 압축 같은 작업을 수행할 때 유용하다. Serialization 해보기 public static void Main() { Memory..

언어/C# 2022.04.03