Загрузка данных
#include <iostream>
#include <vector>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <chrono>
#include <iomanip>
using namespace std;
const int NUM_THREADS = 3;
struct ProcessInfo {
int id;
int burst_time;
int remaining_time;
int arrival_time;
int counter;
int finish_time;
int waiting_time;
int turnaround_time;
};
mutex mtx;
condition_variable cv_scheduler;
condition_variable cv_worker[NUM_THREADS];
bool run_token[NUM_THREADS] = { false };
bool worker_finished_step = false;
bool stop_all = false;
int current_time = 0;
ProcessInfo processes[NUM_THREADS] = {
{0, 6, 6, 0, 0, 0, 0, 0},
{1, 2, 2, 2, 0, 0, 0, 0},
{2, 4, 4, 5, 0, 0, 0, 0}
};
void worker_thread(int id) {
while (true) {
unique_lock<mutex> lock(mtx);
cv_worker[id].wait(lock, [&]() {
return run_token[id] || stop_all;
});
if (stop_all) break;
processes[id].counter += 10;
processes[id].remaining_time--;
current_time++;
cout << " [t = " << setw(2) << current_time << "] | Поток P" << id
<< " | Счётчик: " << setw(3) << processes[id].counter
<< " | Осталось тиков: " << setw(2) << processes[id].remaining_time << "\n";
if (processes[id].remaining_time == 0) {
processes[id].finish_time = current_time;
}
run_token[id] = false;
worker_finished_step = true;
cv_scheduler.notify_one();
lock.unlock();
this_thread::sleep_for(chrono::milliseconds(100));
}
}
int main() {
setlocale(LC_ALL, "Russian");
cout << "+-----------------------------------------------------------------------+\n";
cout << "| МОДЕЛИРОВАНИЕ АЛГОРИТМА SJF (SRTF - ВЫТЕСНЯЮЩИЙ) |\n";
cout << "| Количество потоков: 3 |\n";
cout << "+-----------------------------------------------------------------------+\n\n";
cout << "ВХОДНЫЕ ДАННЫЕ ПРОЦЕССОВ:\n";
cout << "+---------+----------------------+---------------------+\n";
cout << "| Процесс | Время прихода (Тприх)| Время работы (Тисп) |\n";
cout << "+---------+----------------------+---------------------+\n";
for (int i = 0; i < NUM_THREADS; ++i) {
cout << "| P" << processes[i].id << " | "
<< setw(2) << processes[i].arrival_time << " | "
<< setw(2) << processes[i].burst_time << " |\n";
}
cout << "+---------+----------------------+---------------------+\n\n";
cout << "ХОД ВЫПОЛНЕНИЯ:\n";
cout << "-------------------------------------------------------------------------\n";
vector<thread> threads;
for (int i = 0; i < NUM_THREADS; ++i) {
threads.emplace_back(worker_thread, i);
}
int total_remaining = 0;
for (int i = 0; i < NUM_THREADS; ++i) {
total_remaining += processes[i].burst_time;
}
int last_running_id = -1;
while (total_remaining > 0) {
int best_id = -1;
int min_rem = 1e9;
for (int i = 0; i < NUM_THREADS; ++i) {
if (processes[i].arrival_time <= current_time && processes[i].remaining_time > 0) {
if (processes[i].remaining_time < min_rem) {
min_rem = processes[i].remaining_time;
best_id = i;
}
}
}
if (best_id != last_running_id) {
if (last_running_id != -1 && processes[last_running_id].remaining_time > 0) {
cout << "\n >>> [t = " << current_time << "] [ВЫТЕСНЕНИЕ] Поток P"
<< last_running_id << " вытеснен потоком P" << best_id
<< " (остаток времени меньше) <<<\n\n";
} else {
cout << "\n >>> [t = " << current_time << "] Переключение ЦП на поток P"
<< best_id << " <<<\n\n";
}
last_running_id = best_id;
}
{
unique_lock<mutex> lock(mtx);
worker_finished_step = false;
run_token[best_id] = true;
cv_worker[best_id].notify_one();
}
{
unique_lock<mutex> lock(mtx);
cv_scheduler.wait(lock, []() { return worker_finished_step; });
}
total_remaining--;
if (processes[best_id].remaining_time == 0) {
cout << " >>> Поток P" << best_id << " ПОЛНОСТЬЮ ЗАВЕРШЁН в t = "
<< processes[best_id].finish_time << " <<<\n";
}
}
{
unique_lock<mutex> lock(mtx);
stop_all = true;
for (int i = 0; i < NUM_THREADS; ++i) {
cv_worker[i].notify_one();
}
}
for (auto& th : threads) {
if (th.joinable()) {
th.join();
}
}
double avg_waiting = 0;
double avg_turnaround = 0;
cout << "\n-------------------------------------------------------------------------\n";
cout << "ИТОГОВЫЕ РЕЗУЛЬТАТЫ ПЛАНИРОВАНИЯ:\n";
cout << "+---------+----------+----------+----------+-----------------+------------------+\n";
cout << "| Процесс | Тприх | Тисп | Ткон | Полное (Тполн) | Ожидание (Тож) |\n";
cout << "+---------+----------+----------+----------+-----------------+------------------+\n";
for (int i = 0; i < NUM_THREADS; ++i) {
processes[i].turnaround_time = processes[i].finish_time - processes[i].arrival_time;
processes[i].waiting_time = processes[i].turnaround_time - processes[i].burst_time;
avg_waiting += processes[i].waiting_time;
avg_turnaround += processes[i].turnaround_time;
cout << "| P" << processes[i].id << " | "
<< setw(2) << processes[i].arrival_time << " | "
<< setw(2) << processes[i].burst_time << " | "
<< setw(2) << processes[i].finish_time << " | "
<< setw(2) << processes[i].turnaround_time << " | "
<< setw(2) << processes[i].waiting_time << " |\n";
}
avg_waiting /= NUM_THREADS;
avg_turnaround /= NUM_THREADS;
cout << "+---------+----------+----------+----------+-----------------+------------------+\n";
cout << "| СРЕДНИЕ ЗНАЧЕНИЯ: | "
<< fixed << setprecision(2) << setw(5) << avg_turnaround << " | "
<< fixed << setprecision(2) << setw(5) << avg_waiting << " |\n";
cout << "+----------------------------------------------+-----------------+------------------+\n";
cout << "\nНажмите клавишу Enter для выхода из программы...";
cin.get();
return 0;
}