작성
·
318
0
void JobQueue::Push(JobRef&& job)
{
const int32 prevCount = _jobCount.fetch_add(1);
_jobs.Push(job); // WRITE_LOCK
// 첫번째 Job을 넣은 쓰레드가 실행까지 담당
if (prevCount == 0)
{
// 이미 실행중인 JobQueue가 없으면 실행
if (LCurrentJobQueue == nullptr)
{
Execute();
}
else
{
// 여유 있는 다른 쓰레드가 실행하도록 GlobalQueue에 넘긴다
GGlobalQueue->Push(shared_from_this());
}
}
}
// 일감이 너~무 몰리면?
void JobQueue::Execute()
{
LCurrentJobQueue = this;
while (true)
{
Vector<JobRef> jobs;
_jobs.PopAll(OUT jobs);// Lock걸려있기 때문에 다른 스레드에서 중복되는 일감을 가져갈 수 없다
const int32 jobCount = static_cast<int32>(jobs.size());
for (int32 i = 0; i < jobCount; i++)
jobs[i]->Execute();
// 남은 일감이 0개라면 종료
if (_jobCount.fetch_sub(jobCount) == jobCount)
{
LCurrentJobQueue = nullptr;
return;
}
const uint64 now = ::GetTickCount64();
if (now >= LEndTickCount)
{
LCurrentJobQueue = nullptr;
// 여유 있는 다른 쓰레드가 실행하도록 GlobalQueue에 넘긴다
GGlobalQueue->Push(shared_from_this());
break;
}
}
}
1) Excute 매서드
if (_jobCount.fetch_sub(jobCount) == jobCount)
_jobCount가 jobCount보다 작아져서 fetch_sub연산 수행 후 언더 플로우가 발생하여 _jobCount가 엄청나게 늘어나는 문제가 발생하지 않는지 궁금합니다.
답변 1
0
코드의 흐름상 그런 일은 발생할 수 없습니다.
_jobCount를 조작하는 곳이 Push/Pop 할 때 2 곳이고
그 개수를 _jobs와 맞춰주고 있기 때문입니다.