이전에 문제였던 부분

JobQueue를 Execute 했는데 다른 JobQueue까지 처리하게 되었다가 그 작업이 오래 걸리는 경우, 처음에 하려했던 작업이 엄청 뒤로 밀리게 되는 문제가 있다.

이 문제를 어떻게 해결할 수 있을까. 가장 간단한 방법은 이렇다.

 

내가 어떤 JobQueue를 호출하고 있으면 내가 다른 JobQueue에 처음으로 Job을 넣었다고 하더라도 해당 Job을 Execute하지 않도록 만드는 것.

 

방법은 이렇다. TLS에 LCurrentJobQueue 포인터를 추가해 지금 쓰레드가 JobQueue Execute를 하는 중이라면 this 포인터를 넣어주고, 다른 JobQueue에서 Execute를 못하게 막아주는 것. 대신 여유있는 다른 쓰레드가 처리할 수 있도록 GlobalQueue에 처리하려 헀던 JobQueue를 넣어놔 다른 쓰레드가 대신 처리할 수 있도록 한다.

void JobQueue::Push(JobRef&& job)
{
	const int32 prevCount = _jobCount.fetch_add(1);
	_jobs.Push(job);

	if (prevCount == 0)
	{
		if (LCurrentJobQueue == nullptr)
		{
			Execute();
		}
		else
		{
			//여유 있는 다른 쓰레드가 실행하도록 GlobalQueue에 넘긴다.
			GGlobalQueue->Push(shared_from_this());
		}
	}
}

 

지금은 job을 push 하는 경우에만 execute 하고있기 때문에 위와 같은 이유로 미뤄둔 JobQueue를 처리해줄 쓰레드가 없다.

그러니 쓰레드들의 동작을 좀 수정하도록 하자.

void ThreadManager::DoGlobalQueueWork()
{
	while (true)
	{
		uint64 now = ::GetTickCount64();
		if (now > LEndTickCount)
			break;

		JobQueueRef jobQueue = GGlobalQueue->Pop();
		if (jobQueue == nullptr)
			break;

		jobQueue->Execute();
	}
}

void DoWorkerJob(ServerServiceRef& service)
{
	while (true)
	{
		LEndTickCount = ::GetTickCount64() + WORKER_TICK;

		// 네트워크 입출력 처리 -> 인게임 로직까지 (패킷 핸들러에 의해)
		service->GetIocpCore()->Dispatch(10);

		// 글로벌 큐
		ThreadManager::DoGlobalQueueWork();
	}
}

int main()
{
	/*...*/
	for (int32 i = 0; i < 5; ++i)
	{
		GThreadManager->Launch([&service]()
			{
				DoWorkerJob(service);
			});
	}
	DoWorkerJob(service);
	GThreadManager->Join();
}

기존에는 모든 쓰레드에서 iocpcore->dispatch() 만 실행했었는데, 이제 새로 만든 DoWorkerJob을 실행한다.

DoWorkerJob은 iocp 대기를 WORKER_TICK (= 64) 만큼만 하고, 할일이 없거나 iocp작업이 끝나면 DoGlobalJobQueue에서 jobQueue를 하나 꺼낸다. 그리고 정해진 시간까지 joqQueue의 Job들을 처리한다. 처리를 다 못하면 다시 GlobalJobQueue에 넣는 식.

 

이 방법의 장점은 워커쓰레드들이 IOCP 작업과 Job을 처리하는 작업을 둘 다 수행하기 때문에 둘 중 한쪽에 일이 몰리면 자연스럽게 더 많은 쓰레드들이 몰린 일에 더 붙어서 처리하게된다. 음식점으로 따지면 웨이터와 요리사가 일의 양에 따라 실시간으로 적절하게 조율되는 느낌.

'강의 수강 > 게임서버(1)' 카테고리의 다른 글

76. DB Connection  (0) 2025.09.01
75. JobTimer  (0) 2025.08.25
73. JobQueue #4  (0) 2025.08.23
강의를 듣고 다시 확인할 것들 모음  (0) 2025.08.23
72. JobQueue #3  (0) 2025.08.22

+ Recent posts