인프런 커뮤니티 질문&답변

공부해보자님의 프로필 이미지

작성한 질문수

[C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버

JobQueue #1

job queue 흐름에 관하여 질문있습니다

해결된 질문

작성

·

713

1

안녕하세요 항상 좋은 강의 잘 듣고 있습니다.

jobqueue에 대해서 궁금한 점이 생겨 질문드리게 되었습니다.

질문1)

예를 들어 ABCDE쓰레드가 거의 동시에 C_Chat 패킷을 핸들링할 경우,

C_ChatHandler 가 아래와 같고("패킷을 받았습니다" 메세지 전송 추가)

Push의 lock에 접근한 순서가 문자 순서대로 A가 1번 B가 2번...이라면

A쓰레드는 Flush를 수행한 후 클라이언트에게 "패킷을 받았습니다를" 보내주고

나머지 BCDE쓰레드들은 Flush를 수행하지 않고 큐에 넣기만 하고 "패킷을 받았습니다"라는 메세지를 보내게 되는 게 맞나요?

질문2) 위 내용이 맞다면

A쓰레드는 단지 1등으로 Push의 lock에 접근했다는 이유로 Flush(요리)를 수행하고,

응답("패킷을 받았습니다"라는 메시지 Send // Push로 등록한 action이 아닌 Push 이후의 흐름들)을 Flush수행 시간만큼 늦게 보내게 되는 것인데 뭔가 불합리?하다고 느껴집니다. 이런 정책을 많이 사용하나요?

답변 5

2

Rookiss님의 프로필 이미지
Rookiss
지식공유자

쓰레드는 많아야 몇십 단위이고
유저는 몇천명인 상황이라 어차피 100% 공정할 순 없습니다.
그리고 저렇게 room.Push를 연이어서 해야 하는 상황은 비현실적이지만
꼭 해야 한다면 Push() 내부에서 또 Push를 해서 우선순위를 끌어 올릴 수 있습니다.

1

Rookiss님의 프로필 이미지
Rookiss
지식공유자

다시 보니 제가 위 질문을 잘못 이해했는데,
BCDE가 실행되지 않는다가 아니고
A가 늦게 실행되는 것이 불공평하다 느끼시는 것이군요?

위 부분에서 room이 끝난 다음에 보내는
"패킷을 받았습니다" 패킷은 사실 게임 입장에서 보면 아무런 의미가 없습니다.
실제로 중요한 것은 모두의 경합이 일어나는
'게임' 내부에서 누가 먼저 실행권을 얻느냐입니다.
그 안에서 전투와 이동과 온갖 로직이 실행되기 때문이죠.
JobQueue를 이용하면 Room에 먼저 Action을 Push한 순서대로 실행이 보장되니
가장 공평한 상황이라고 볼 수 있습니다.

만약에 정말로 저 위치의 공평함이 중요하다면
Room을 Push를 하는 애 중 처음으로 들어온 애가 실행하는게 아니라,
그냥 별도로 실행하는 애를 배정해서 돌리면 그만입니다.
(그렇게 되면 Push 하는 애들은 정말 일감 Push만 하게 되겠죠)

1

Rookiss님의 프로필 이미지
Rookiss
지식공유자

1+2)
그렇지 않습니다.
누군가가 이미 실행중이라면
BCDE는 큐에만 넣고 빠져나오는 것은 맞지만,

A가 자기 일감을 실행하면서, 추가로 온 애들도 같이 실행해주게 됩니다.
큐는 공용으로 활용하기 때문이죠.

Flush를 할 때는 lock을 걸지 않은 상태라는 것을 유심히 보시기 바랍니다.

Flush할 때 Pop된 일감은 

A가 실행중이라고 해서 A가 넣은 애라는 보장은 없습니다.

0

늦은시간에 답변 감사합니다!

"패킷을 받았습니다" 메세지는 질문을 위한 예시였고 

만약 패킷 핸들러에서 2가지 이상의 Job을 

멀티쓰레드 환경이기에 완벽하지는 않지만 어느 정도 순서에 맞추어 Push시키고 싶다면

별도로 실행을 담당하는 쓰레드를 배정해서 구현하면 된다 라고 이해하면 될까요?

0

빠른변감사합니다!

하지만 반복해서 답변을 보고도 잘 이해를 하지 못하였습니다...

A B C D E 쓰레드 순으로 Push의 lock부분에 접근하였다면(jobQueue는 비어있는 상태, _flush = false)

A가 Flush를 담당하게 되고(A가 요리사)

A가 Flush를 하는 도중에(Flush가 오랜 시간이 걸린다고 가정, _flush = true) B C D E 쓰레드가 Push 한다면

B C D E 는 jobQueue에 넣기만하고 다음 흐름을 진행하지않나요?

즉,  A가 B C D E들이 등록한 job까지 처리를 해야하는것 아닌가요?

만약 그렇다면 처음 질문의 2번 질문처럼 불합리하지않나요?

(Push 이후의 흐름이 Flush 수행시간 만큼 늦게 실행됨,

예를 들어 위 질문에선 A쓰레드는 패킷을 받았다는 메세지를 Flush를 모두 수행하고나서 Send하게됨

반면, A보다 늦게 접근한 쓰레드들은 일찍 메세지를 Send함)