Я пытаюсь реализовать пул потоков для упражнения. После создания потока они будут ждать, пока в очереди не будет хотя бы одного задания. таким образом, я использовал условную переменную с ожиданием. Первая проблема: последнее ожидание потока никогда не выходит из цикла, даже установка 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 секундам, или оставшейся продолжительности задания). после сна поток обновляет время выполнения задания. когда больше нет доступных заданий, потоки должны завершиться, пока основной процесс застрял в соединении, пока все они не будут завершены.