공부 학습

게임 서버 공부_멀티스레드 2

Multitab 2023. 2. 28. 18:03

정보 출처 : 게임 서버 프로그래밍 교과서 (배현직 - 길벗출판사)

게임서버에서 멀티 스레드를 이용하는 경우

  • 서버 프로세스 당 이용되는 게임 정보가 많을때 (MMO게임)

  • 서버 한대의 프로세스가 여러 CPU의 연상량을 동원해야할때

  • 별도의 비동기 함수를 사용할수 없으며 디바이스 타임이 발생할때

  • 서로 다른 게임 단위가 같은 메모리 공간에 업근해야할때

    게임서버에서 상황에 따른 CPU개수와 스레드 생성 개수의 관계

    • 서버가 CPU 연산만을 수행한다면 스레드와 CPU개수가 동일해도 효율적
    • 서버가 DB나 외부 장치 연산이 많으면 디바이스 타임으로 인해 놀동안 배정될 여유 스레드를 확보하는게 효율적

    이벤트

    • 쓰레드를 깨우는 장치 : Rest = 0 , Set = 1
    • window 기준 이벤트에는 자동 스레드와 수동 스레드가 있음
    • 수동스레드
      Event event1;
      void Tread1{
      event1.Wait();
      event1.SetEvent(0); // 수동으로 0으로 변경해줌
      }
      void Tread2{
      event1.Wait();//Event가 1로 변경
      }
    • 자동스레드
      Event event1;
      void Tread1{
      event1.Wait();
      }
      void Tread2{
      event1.Wait();
      }
      void Tread3{
      event1.PauseEvent();// 자동으로 한번한 1로 변경하고 0으로 돌려줌
      }

    세마포어

    • 일정 개수의 스레드가 자원에 접근할 수 있도록 하는 장치
      Semaphore sema1;
      void Main(){
      sema1 = new Semaphore(2);// 2개만 접근 허용하고 이후 나머지 접근허가
      }
      void Thread1(){
      sema1.Wait();
      sema1.Release();
      }
      void Thread2(){
      sema1.Wait();
      sema1.Release();
      }
      void Thread3(){
      sema1.Wait();
      sema1.Release();
      }
    • 세마포어의 다른 용도: Thread Queue구현
      • 1 이상의 상태값을 셋팅할 수 있는 특성을 이용
        Queue queue;
        Semaphore queueIsNotEmpty;
        

void Main(){
queueIsNotEmpty = new Semaphore(0);
}
void Tread1(){
while(true){
queueIsNotEmpty.Wait();
queue.PopFront();
}
}
void Tread1(){
while(true){
queue.PushBack();
queueIsNotEmpty.Release();
}
}


### 원자조작 (Atomic Operation)
- 안전하게 스레드 접근을 할수 있는 특수 변수
```cpp
volaile int a = 0;
int r = AtomicAdd(&a, 3);
int r = AtomicExchange(&a, 10);
int r = AtomicCompareExchange(&a, 10, 100);//10이 있을때만 100으로 바꾼다

멀티스레드 프로그래밍시 주의할점

  • 읽기, 쓰기를 모두 잡금하지 않기
  • 잠금 순서 규칙을 준수하고, 최대한 단순하게 유지하라
  • 잠금 범위의 뭉탱이 크기를 적절하게 나누어라
  • 디바이스 타임이 존재하는데 잠금을 하지마라
  • 잠금이 되어진 리소스가 로컬변수로 존재하는 상태에서 작업을 시도하는 경우를 주의하라
  • 잠금된 뮤텍스나 임계영역을 삭제하지마라
  • 보호중인 데이터의 일관성이 깨지는 경우를 경계하라 -> 가능하면 원자조작, 병렬구조를 지원하는 형식을 사용하라