我正在尝试为练习实现一个线程池。创建线程后,它们将等待,直到作业队列中至少有一个作业。因此,我使用了一个条件变量来等待一段时间。第一个问题:等待的最后一个线程永远不会退出循环,即使放置if并检查正在进行的作业数量也无济于事。 第二个问题:只有一定数量的线程实际上完成了执行作业的循环,导致进程在联接后停止。 我该如何解决这些问题?
jobScheduler.cpp
void jobScheduler::threadFunction(int id, std::mutex& loadingJobsMutex,
std::mutex& onGoingJobsMutex, std::mutex& finishedJobsMutex, std::mutex& coutMutex,
std::mutex& timeMutex)
{
job temp;
int execTime = 0;
int startTime;
while (true) {
std::unique_lock<std::mutex> lkLoading(loadingJobsMutex);
if (this->onGoingJobsCount == 9)
break;
this->waitList.wait(lkLoading);
if (this->jobsCount > 0) {
this->jobsCount--;
this->onGoingJobsCount++;
break;
}
}
while (this->onGoingJobsCount > 0) {
{
std::unique_lock<std::mutex> lkOnGoing(onGoingJobsMutex);
while (this->onGoingJobs.empty()) {
this->waitOnGoing.wait(lkOnGoing);
}
temp = this->onGoingJobs.front();
temp.updateWaitTime(this->time - temp.getLastExecution());
this->onGoingJobs.pop();
}
if (temp.getDurationTime() - temp.getExecutionTime() < this->timeSlot) {
Sleep(temp.getDurationTime() - temp.getExecutionTime());
execTime = temp.getDurationTime() - temp.getExecutionTime();
temp.updateExecutionTime(execTime);
}
else {
execTime = timeSlot;
Sleep(this->timeSlot);
temp.updateExecutionTime(timeSlot);
}
if (temp.getDurationTime() == temp.getExecutionTime()) {
{
std::unique_lock<std::mutex> lkFinished(finishedJobsMutex);
this->finishedJobs.push_back(temp.getId());
this->onGoingJobsCount--;
}
}
else {
{
std::lock_guard<std::mutex> lkTime(timeMutex);
if (startTime + execTime > this->time) {
this->time = startTime + execTime;
}
temp.updateLastExecution(this->time);
}
{
std::unique_lock<std::mutex> lkOnGoing(onGoingJobsMutex);
this->onGoingJobs.push(temp);
this->waitOnGoing.notify_one();
}
}
}
}
其结果应该是:线程应该等待,直到正在进行的队列中有作业为止,这些线程由主进程插入。当插入一个时,它应该模拟一个带有睡眠的作业的执行(其持续时间等于3秒的时间,即该作业的剩余持续时间)。休眠后,线程将更新作业的执行时间。如果没有更多可用的作业,则线程应在主进程停留在连接上的同时完成,直到所有线程都完成为止。