정보 출처 : 게임 서버 프로그래밍 교과서 (배현직 - 길벗출판사)
게임서버에서 멀티 스레드를 이용하는 경우
서버 프로세스 당 이용되는 게임 정보가 많을때 (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;
- 1 이상의 상태값을 셋팅할 수 있는 특성을 이용
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으로 바꾼다
멀티스레드 프로그래밍시 주의할점
- 읽기, 쓰기를 모두 잡금하지 않기
- 잠금 순서 규칙을 준수하고, 최대한 단순하게 유지하라
- 잠금 범위의 뭉탱이 크기를 적절하게 나누어라
- 디바이스 타임이 존재하는데 잠금을 하지마라
- 잠금이 되어진 리소스가 로컬변수로 존재하는 상태에서 작업을 시도하는 경우를 주의하라
- 잠금된 뮤텍스나 임계영역을 삭제하지마라
- 보호중인 데이터의 일관성이 깨지는 경우를 경계하라 -> 가능하면 원자조작, 병렬구조를 지원하는 형식을 사용하라
'공부 학습' 카테고리의 다른 글
Rust 개발 환경 설정 및 빌드 방법 (1) | 2024.09.22 |
---|---|
게임 서버 공부_네트워크 (0) | 2023.02.28 |
게임 서버 공부_멀티스레드 프로그래밍 1 (0) | 2023.02.28 |
Docker 명령어 정리 (0) | 2022.12.17 |
디자인 패턴 - 관계형 패턴 (0) | 2022.11.08 |