Проблемы с домашним заданием из пула потоков - PullRequest
0 голосов
/ 21 июня 2019

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

...