Не работает код на C++ в соответствии с нужной логикой

По условию задачи нужно на C++ написать программу моделирования обращений к серверу. Запросы поступают в якобы случайные моменты времени, одновременно может прийти до 10 запросов. Структура данных - очередь, библиотечные контейнеры использовать запрещено.

Output должен выглядеть так:

Обрабатывается запрос 32 Поступило 2: 33, 34

Обрабатывается запрос 33 Поступило 1: 35

Обрабатывается запрос 34 Поступило 0:

Обрабатывается запрос 35 Поступило 0:

Сервер простаивает Поступило 0:

Обрабатывается запрос 36 Поступило 5: 36, 37, 38, 39, 40

У меня output выглядит так:

Сервер простаивает Поступило 0

Обрабатывается запрос 1 Поступило 1: 1

Обрабатывается запрос 1 Поступило 2: 2, 3

Обрабатывается запрос 1 Поступило 0:

Обрабатывается запрос 1 Поступило 1: 4

Обрабатывается запрос 1 Поступило 0:

Обрабатывается запрос 1 Поступило 2: 5, 6

Очевидно, что что-то работает не так, но я не могу понять, как эту проблему исправить. Пытаюсь исправить - становится еще хуже, чем было. Помогите пожалуйста изменить код так, чтобы в запросы сменяли друг друга и шли по очереди.

Вот код:

#include <iostream>
#include <random>
#include <chrono>
#include <thread>

// Константы для моделирования
const int DURATION_MINUTES = 1; // Время моделирования в минутах
const int ARRIVAL_RATE = 100;    // Средняя плотность запросов в минуту
const double PROCESSING_TIME = 0.5; // Время обработки одного запроса в секундах
const int TIME_STEP_MS = 500;    // Шаг времени в миллисекундах
const int MAX_SIMULTANEOUS_REQUESTS = 10; // Максимальное число одновременных запросов

// Структура запроса
struct Request {
    int id;
    std::chrono::steady_clock::time_point arrival_time;
};

// Функция добавления запроса в очередь
void add_request(Request* request_queue[], int& request_id, std::chrono::steady_clock::time_point current_time) {
    Request* new_request = new Request{request_id++, current_time};
    int i = 0;
    while (request_queue[i] != nullptr) {
        i++;
    }
    request_queue[i] = new_request;
}

// Функция удаления запроса из очереди
void remove_request(Request* request_queue[]) {
    if (request_queue[0] != nullptr) {
        Request* front_request = request_queue[0];
        for (int i = 0; i < MAX_SIMULTANEOUS_REQUESTS - 1; ++i) {
            request_queue[i] = request_queue[i + 1];
        }
        request_queue[MAX_SIMULTANEOUS_REQUESTS - 1] = nullptr;
        std::cout << "Запрос " << front_request->id << " удален." << std::endl;
        delete front_request;
    } else {
        std::cout << "Очередь пуста, нечего удалять." << std::endl;
    }
}

// Функция отображения очереди
void display_queue(Request* request_queue[]) {
    std::cout << "Текущая очередь запросов: ";
    for (int i = 0; i < MAX_SIMULTANEOUS_REQUESTS; ++i) {
        if (request_queue[i] != nullptr) {
            std::cout << request_queue[i]->id << " ";
        } else {
            std::cout << "0 ";
        }
    }
    std::cout << std::endl;
}

// Функция отображения меню
void display_menu(Request* request_queue[], int& request_id, std::chrono::steady_clock::time_point current_time) {
    int choice;
    do {
        std::cout << "\nМеню:\n";
        std::cout << "1. Добавить запрос\n";
        std::cout << "2. Удалить запрос\n";
        std::cout << "3. Показать очередь\n";
        std::cout << "4. Выход\n";
        std::cout << "Введите ваш выбор: ";
        std::cin >> choice;

        switch (choice) {
            case 1:
                add_request(request_queue, request_id, current_time);
                std::cout << "Запрос добавлен." << std::endl;
                break;
            case 2:
                remove_request(request_queue);
                break;
            case 3:
                display_queue(request_queue);
                break;
            case 4:
                std::cout << "Выход из программы.\n";
                break;
            default:
                std::cout << "Неверный выбор, попробуйте снова.\n";
        }
    } while (choice != 4);
}

// Функция моделирования работы сервера
void simulate_server() {
    Request* request_queue[MAX_SIMULTANEOUS_REQUESTS] = {nullptr};
    std::default_random_engine generator;
    std::poisson_distribution<int> distribution(ARRIVAL_RATE / 120.0); // Плотность запросов за 0.5 секунды
    int request_id = 1;
    int max_queue_length = 0;
    double max_wait_time = 0.0;
    double max_idle_time = 0.0;
    double current_idle_time = 0.0;

    auto start_time = std::chrono::steady_clock::now();
    auto current_time = start_time;

    for (int step = 0; step < DURATION_MINUTES * 60 * 2; ++step) {
        // Генерация новых запросов
        int num_new_requests = distribution(generator);
        if (num_new_requests > MAX_SIMULTANEOUS_REQUESTS) num_new_requests = MAX_SIMULTANEOUS_REQUESTS; // Ограничение на MAX_SIMULTANEOUS_REQUESTS запросов одновременно

        for (int i = 0; i < num_new_requests; ++i) {
            add_request(request_queue, request_id, current_time);
        }

        // Обработка запросов
        if (request_queue[0] != nullptr) {
            Request* current_request = request_queue[0];

            auto wait_time = std::chrono::duration_cast<std::chrono::milliseconds>(current_time - current_request->arrival_time).count() / 1000.0;
            if (wait_time > max_wait_time) {
                max_wait_time = wait_time;
            }

            std::cout << "Обрабатывается запрос " << current_request->id<< " \t";
            std::cout << "Поступило " << num_new_requests << ": ";
            for (int i = 0; i < num_new_requests; ++i) {
                std::cout << request_id - num_new_requests + i << (i == num_new_requests - 1 ? "" : ", ");
            }
            std::cout << std::endl;

            current_idle_time = 0.0;
        } else {
            std::cout << "Сервер простаивает\t\tПоступило " << num_new_requests << std::endl;
            current_idle_time += TIME_STEP_MS / 1000.0;
            if (current_idle_time > max_idle_time) {
                max_idle_time = current_idle_time;
            }
        }

        // Обновление максимальной длины очереди
        int current_queue_length = 0;
        for (int i = 0; i < MAX_SIMULTANEOUS_REQUESTS; ++i) {
            if (request_queue[i] != nullptr) {
                current_queue_length++;
            }
        }
        if (current_queue_length > max_queue_length) {
            max_queue_length = current_queue_length;
        }

        // Имитация времени шага
        std::this_thread::sleep_for(std::chrono::milliseconds(TIME_STEP_MS));
        current_time += std::chrono::milliseconds(TIME_STEP_MS);
    }

    // Вывод результатов
    std::cout << "Максимальное время непрерывного простоя сервера: " << max_idle_time << " секунд" << std::endl;
    std::cout << "Максимальная длина очереди запросов: " << max_queue_length << std::endl;
    std::cout << "Максимальное время ожидания обслуживания: " << max_wait_time << " секунд" << std::endl;

    // Переход в режим меню
    display_menu(request_queue, request_id, current_time);
}

int main() {
    simulate_server();
    return 0;
}

Ответы (1 шт):

Автор решения: GxdTxnz

В целом, можно попробовать внести следующие изменения:

void add_request(Request* request_queue[], int& request_id, std::chrono::steady_clock::time_point current_time) {
    Request* new_request = new Request{request_id++, current_time};
    int i = 0;
    // Поиск первой пустой ячейки в очереди
    while (request_queue[i] != nullptr && i < MAX_SIMULTANEOUS_REQUESTS) {
        i++;
    }
    // Если найдена пустая ячейка, добавляем новый запрос
    if (i < MAX_SIMULTANEOUS_REQUESTS) {
        request_queue[i] = new_request;
    }
}
void remove_request(Request* request_queue[]) {
    if (request_queue[0] != nullptr) {
        Request* front_request = request_queue[0];
        // Сдвигаем оставшиеся запросы в очереди на одну позицию вперед
        for (int i = 0; i < MAX_SIMULTANEOUS_REQUESTS - 1; ++i) {
            request_queue[i] = request_queue[i + 1];
        }
        request_queue[MAX_SIMULTANEOUS_REQUESTS - 1] = nullptr;
        // Удаляем обработанный запрос и освобождаем память
        delete front_request;
    }
}
    for (int step = 0; step < DURATION_MINUTES * 60 * 2; ++step) {
        int num_new_requests = distribution(generator);
        if (num_new_requests > MAX_SIMULTANEOUS_REQUESTS) 
            num_new_requests = MAX_SIMULTANEOUS_REQUESTS;

        for (int i = 0; i < num_new_requests; ++i) 
            add_request(request_queue, request_id, current_time);

        if (request_queue[0] != nullptr) {
            Request* current_request = request_queue[0];
            auto wait_time = std::chrono::duration_cast<std::chrono::milliseconds>(current_time - current_request->arrival_time).count() / 1000.0;
            if (wait_time > max_wait_time) 
                max_wait_time = wait_time;

            std::cout << "Обрабатывается запрос " << current_request->id << " \t";
            std::cout << "Поступило " << num_new_requests << ": ";
            for (int i = 0; i < num_new_requests; ++i) 
                std::cout << request_id - num_new_requests + i << (i == num_new_requests - 1 ? "" : ", ");
            std::cout << std::endl;

            remove_request(request_queue);  // Удаляем обработанный запрос
            current_idle_time = 0.0;
        } else {
            std::cout << "Сервер простаивает\t\tПоступило " << num_new_requests << std::endl;
            current_idle_time += TIME_STEP_MS / 1000.0;
            if (current_idle_time > max_idle_time) 
                max_idle_time = current_idle_time;
        }

        int current_queue_length = 0;
        for (int i = 0; i < MAX_SIMULTANEOUS_REQUESTS; ++i) 
            if (request_queue[i] != nullptr) 
                current_queue_length++;
        if (current_queue_length > max_queue_length) 
            max_queue_length = current_queue_length;

        std::this_thread::sleep_for(std::chrono::milliseconds(TIME_STEP_MS));
        current_time = std::chrono::steady_clock::now(); //меняем время
    }
→ Ссылка