Загрузка данных


#include <iostream>
#include <vector>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <chrono>
#include <iomanip>
#include <algorithm>

using namespace std;

const int NUM_THREADS = 4;

struct ProcessInfo {
    int id;
    int burst_time;
    int remaining_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 = false;
bool stop_all = false;
int current_time = 0;

ProcessInfo processes[NUM_THREADS] = {
    {0, 5, 5, 0, 0, 0, 0},
    {1, 3, 3, 0, 0, 0, 0},
    {2, 7, 7, 0, 0, 0, 0},
    {3, 1, 1, 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;

        while (processes[id].remaining_time > 0) {
            processes[id].counter += 10;
            processes[id].remaining_time--;
            current_time++;

            cout << "[Время " << setw(2) << current_time << "] Поток P" << id
                 << " выполняется | Счётчик = " << setw(3) << processes[id].counter
                 << " | Осталось тиков: " << processes[id].remaining_time << "\n";

            lock.unlock();
            this_thread::sleep_for(chrono::milliseconds(800));
            lock.lock();
        }

        processes[id].finish_time = current_time;

        run_token[id] = false;
        worker_finished = true;
        cv_scheduler.notify_one();
    }
}

int main() {
    setlocale(LC_ALL, "Russian");

    cout << "========================================================\n";
    cout << "  Планирование: SJF (Shortest Job First)\n";
    cout << "========================================================\n\n";

    vector<thread> threads;
    for (int i = 0; i < NUM_THREADS; ++i) {
        threads.emplace_back(worker_thread, i);
    }

    vector<int> ready_order;
    for (int i = 0; i < NUM_THREADS; ++i) {
        ready_order.push_back(i);
    }

    sort(ready_order.begin(), ready_order.end(), [](int a, int b) {
        return processes[a].burst_time < processes[b].burst_time;
    });

    for (int current_id : ready_order) {
        cout << "\n>>> Планировщик SJF выбрал P" << current_id 
             << " (длительность: " << processes[current_id].burst_time << " тиков) <<<\n";

        {
            unique_lock<mutex> lock(mtx);
            worker_finished = false;
            run_token[current_id] = true;
            cv_worker[current_id].notify_one();
        }

        {
            unique_lock<mutex> lock(mtx);
            cv_scheduler.wait(lock, []() { return worker_finished; });
        }

        cout << ">>> Поток P" << current_id << " завершён в t = " 
             << processes[current_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 << "Процесс | Время работы (Tисп) | Полное время (Tполн) | Время ожидания (Тож)\n";
    cout << "-------------------------------------------------------------------------\n";

    for (int i = 0; i < NUM_THREADS; ++i) {
        processes[i].turnaround_time = processes[i].finish_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].burst_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) << avg_turnaround << "\n";
    cout << "Среднее время ожидания:          " << fixed << setprecision(2) << avg_waiting << "\n";
    cout << "=========================================================================\n";

    cout << "\nДля выхода нажмите Enter...";
    cin.get();

    return 0;
}