ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Server
    👩🏻‍💻 c# 2023. 9. 1. 08:58

     

    서버 개론

    • 다른 컴퓨터에서 연결이 가능하도록 대기 상태로 상시 실행중인 프로그램 - <영업중인 식당>
    • 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

    • 바로 메인 메모리에 저장하는게 아니고 캐시같은 기억 장치들에 저장 후 추후 메인 메모리에 저장
    • 캐시 철학
      1. Temporal locality
        • 시간적으로보면, 방금 주문한 테이블에서 추가 주문이 나올 확률이 높다. 방금 주문한 걸 메모해 놓으면 편하지 않을까?
      2. Spacial 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