-
서버 개론
- 다른 컴퓨터에서 연결이 가능하도록 대기 상태로 상시 실행중인 프로그램 - <영업중인 식당>
- Web server (HTTP)
- 손님이 음식을 받아서 떠나면, 그 이후론 연결이 끊긴다 (take-out 전문)
- 손님에게 먼저 접근할 일이 없고
- 질의 응답 형태
- 프레임워크를 하나 골라서 사용 (asp.net, nodejs, django, php…)
- Game server (TCP server, binary server, stateful server…)
- 서빙 직원이 와서 물어볼수도 있고
- 실시간 interaction
- 요청/갱신 횟수가 많다
- 최적의 프레임워크라는 것이 존재 X
Multithread 입문
- 스케쥴링 / 기아 현상
- 직원 (thread) 효율적 관리
쓰레드 생성
- Thread t = new Thread(MainThread);
- t.Start()
- t.IsBackground
- t.Join()
- 정직원 같은 개념
- 원하는 갯수 만큼 생성 가능 - but CPU 코어 수와 최대한 맞춰주는게 맞다. 많아질 수록 부하가 올라감
using System; using System.Threading; namespace ServerCore { class Program { static void MainThread() { for (int i = 0; i < 5; i ++ ) Console.WriteLine("Hello Thread!"); } static void Main(string[] args) { Thread t = new Thread(MainThread); t.Name = "Test Thread"; t.IsBackground = true; //false 인 상태가 디폴 t.Start(); Console.WriteLine("Waiting for thread!"); t.Join(); //끝날때까지 기다린다 Console.WriteLine("hello"); } } }
ThreadPool 로 관리 하는 방법
- 단기 알바 / ThreadPool 은 인력사무소 같은 것. (정해진 인력). 가급적 짧은 일감을 넘겨줘야지 안그러면 먹통이 된다
- ThreadPool.SetMinThreads(1,1);
- ThreadPool.SetMaxThreads(5,5);
- ThreadPool.QueueUserWorkItem(MainThread);
using System; using System.Threading; using System.Threading.Tasks; namespace ServerCore { class Program { static void MainThread(object state) { for (int i = 0; i < 5; i ++ ) Console.WriteLine("Hello Thread!"); } static void Main(string[] args) { ThreadPool.SetMinThreads(1, 1); ThreadPool.SetMaxThreads(5, 5); Task t = new Task(() => { while (true) { } }, TaskCreationOptions.LongRunning); t.Start(); for (int i = 0; i < 5; i++) ThreadPool.QueueUserWorkItem((obj) => { while (true) { } }); ThreadPool.QueueUserWorkItem(MainThread); //단기 알바 - 일감 넘겨줌. 인력사무소 (정해진 인력). 가급적 짧은 일감을 넘겨줘야지 안그러면 먹통 됨 //Thread t = new Thread(MainThread); //정직원, 원하는 갯수 만큼 생성 가능 - but CPU 코어 수와 최대한 맞춰주는게 맞다. 많아질 수록 부하가 올라감 //t.Name = "Test Thread" //t.IsBackground = true; //false 인 상태가 디폴트 //t.Start(); //Console.WriteLine("Waiting for thread!"); //t.Join(); //끝날때까지 기다린다 //Console.WriteLine("hello"); while(true) { } } } }
- 그러므로: 오래걸리는 일 → task 로 관리
- Task t = new Task(() => { while (true) { } }, TaskCreationOptions.LongRunning); //두번째 인자로 옵션 -> 오래걸린다고 알려주고 효율적으로 관리 t.Start();
using System; using System.Threading; using System.Threading.Tasks; namespace ServerCore { class Program { static void MainThread(object state) { for (int i = 0; i < 5; i ++ ) Console.WriteLine("Hello Thread!"); } static void Main(string[] args) { ThreadPool.SetMinThreads(1, 1); ThreadPool.SetMaxThreads(5, 5); for (int i = 0; i < 5; i++) { Task t = new Task(() => { while (true) { } }, TaskCreationOptions.LongRunning); //두번째 인자로 옵션 -> 오래걸린다고 알려주고 효율적으로 관리 t.Start(); } ThreadPool.QueueUserWorkItem(MainThread); //단기 알바 - 일감 넘겨줌. 인력사무소 (정해진 인력). 가급적 짧은 일감을 넘겨줘야지 안그러면 먹통 됨 //Thread t = new Thread(MainThread); //정직원, 원하는 갯수 만큼 생성 가능 - but CPU 코어 수와 최대한 맞춰주는게 맞다. 많아질 수록 부하가 올라감 //t.Name = "Test Thread" //t.IsBackground = true; //false 인 상태가 디폴트 //t.Start(); //Console.WriteLine("Waiting for thread!"); //t.Join(); //끝날때까지 기다린다 //Console.WriteLine("hello"); while(true) { } } } }
컴파일러 최적화
- 최적화 하지 말라고 volatile 키워드 (debug > release 모드로 바꿀때 생길수 있는 문제 방지)
- 하지만 이 키워드 비추, 쓸일 없다 -> 다른 키워드 나중에 배울 것
using System; using System.Threading; using System.Threading.Tasks; namespace ServerCore { class Program { volatile static bool _stop = false; //최적화 하지 말라고 volatile (debug > release 모드로 바꿀때 생길수 있는 문제 방지). 하지만 이 키워드 비추 -> 다른 키워드 나중에 배울 것 static void ThreadMain() { Console.WriteLine("Thread start"); while (_stop == false) { } Console.WriteLine("Thread Stop"); } static void Main(string[] args) { Task t = new Task(ThreadMain); t.Start(); Thread.Sleep(1000); //1초간 대기 _stop = true; Console.WriteLine("Stop 호출 "); Console.WriteLine("종료 대기중 "); t.Wait(); //끝나는거 확인 Console.WriteLine("종료 성공 "); } } }
Cache
- 바로 메인 메모리에 저장하는게 아니고 캐시같은 기억 장치들에 저장 후 추후 메인 메모리에 저장
- 캐시 철학
- Temporal locality
- 시간적으로보면, 방금 주문한 테이블에서 추가 주문이 나올 확률이 높다. 방금 주문한 걸 메모해 놓으면 편하지 않을까?
- Spacial locality
- 공간적으로 보면, 방금 주문한 사람 근처에 있는 사람이 주문을 할 확률이 높다. 방금 주문한 사람과 합석하고 있는 사람들의 주문 목록도 메모해 놓으면 편하지 않을까?
- Temporal locality
- 멀티쓰레드의 경우 → 각 코어마다 미니 수첩 (캐시) 갖고 있는데 서로 공유하는 건 아니니까 → 문제 생길 수 있다
static void Main(string[] args) { //공간적 이점을 활용한다 int[,] arr = new int[10000, 10000]; { long now = DateTime.Now.Ticks; for (int y = 0; y < 10000; y++) for (int x = 0; x < 10000; x++) arr[y, x] = 1; long end = DateTime.Now.Ticks; Console.WriteLine($"(y,x) 순서 걸린 시간 {end - now}"); } { //공간적 이점을 활용 x long now = DateTime.Now.Ticks; for (int y = 0; y < 10000; y++) for (int x = 0; x < 10000; x++) arr[x, y] = 1; long end = DateTime.Now.Ticks; Console.WriteLine($"(x,y) 순서 걸린 시간 {end - now}"); } }
✨ 개인 공부 기록용 블로그입니다. 잘못된 부분이 있을 경우
댓글 혹은 메일로 알려주시면 감사하겠습니다! 🤓
'👩🏻💻 c#' 카테고리의 다른 글
자료구조와 알고리즘 (0) 2023.08.01 Section 1 ~ Section: 7 (0) 2023.08.01