Не работает код на 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 шт):
В целом, можно попробовать внести следующие изменения:
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(); //меняем время
}