/
nanezz
/
mutex3
Обзор
Документация
Войти
/
nanezz
/
mutex3
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
mutex2.cpp
204 строки
5 KB
nanezz
Create: mutex2.cpp, mutex2.slnx
03 июл 2026, 23:25
Верифицирован
03 июл 2026, 23:25
f4df06f
Код
Авторство
О чём код?
#include <iostream> #include <thread> #include <vector> #include <chrono> #include <random> #include <mutex> #include <iomanip> #include <sstream> #include <atomic> #include <condition_variable> #ifdef _WIN32 #include <windows.h> #else #include <unistd.h> #endif void clearScreen() { #ifdef _WIN32 system("cls"); #else system("clear"); #endif } void setCursorPosition(int row, int col) { #ifdef _WIN32 COORD coord; coord.X = static_cast<SHORT>(col); coord.Y = static_cast<SHORT>(row); SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord); #else std::cout << "\033[" << (row + 1) << ";" << (col + 1) << "H"; #endif } const int NUM_THREADS = 5; const int CALCULATION_LENGTH = 30; const int PROGRESS_BAR_WIDTH = 30; const int UPDATE_DELAY_MS = 100; struct ThreadState { int id; std::thread::id thread_id; int progress; bool finished; std::chrono::steady_clock::time_point start_time; std::chrono::steady_clock::time_point end_time; bool has_error; std::string error_symbol; }; std::vector<ThreadState> states(NUM_THREADS); std::mutex cout_mutex; std::atomic<bool> all_finished{ false }; std::condition_variable cv; std::mutex cv_mutex; std::random_device rd; std::mt19937 gen(rd()); std::uniform_real_distribution<> error_dist(0.0, 1.0); const double ERROR_PROBABILITY = 0.15; void workerThread(int thread_index) { auto& st = states[thread_index]; st.id = thread_index; st.thread_id = std::this_thread::get_id(); st.progress = 0; st.finished = false; st.has_error = false; st.start_time = std::chrono::steady_clock::now(); for (int step = 0; step < CALCULATION_LENGTH; ++step) { std::this_thread::sleep_for(std::chrono::milliseconds(UPDATE_DELAY_MS)); if (error_dist(gen) < ERROR_PROBABILITY) { st.has_error = true; st.error_symbol = "!"; } else { st.has_error = false; st.error_symbol = ""; } st.progress = step + 1; cv.notify_one(); } st.finished = true; st.end_time = std::chrono::steady_clock::now(); cv.notify_one(); } void renderProgress() { clearScreen(); while (!all_finished.load()) { std::unique_lock<std::mutex> lock(cv_mutex); cv.wait_for(lock, std::chrono::milliseconds(50)); for (int i = 0; i < NUM_THREADS; ++i) { const auto& st = states[i]; std::ostringstream oss; oss << "Поток " << std::setw(2) << (st.id + 1) << " ["; oss << st.thread_id; oss << "] "; int filled = static_cast<int>(static_cast<double>(st.progress) / CALCULATION_LENGTH * PROGRESS_BAR_WIDTH); for (int j = 0; j < PROGRESS_BAR_WIDTH; ++j) { if (j < filled) { if (st.has_error && j == filled - 1) { #ifdef _WIN32 oss << '!'; #else oss << "\033[31m!\033[0m"; #endif } else { oss << '='; } } else { oss << ' '; } } oss << "| " << std::setw(3) << (st.progress * 100 / CALCULATION_LENGTH) << "%"; if (st.finished) { auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(st.end_time - st.start_time); oss << " (время: " << duration.count() << " мс)"; } setCursorPosition(i, 0); std::cout << oss.str() << std::flush; } bool all_done = true; for (const auto& st : states) { if (!st.finished) { all_done = false; break; } } if (all_done) { all_finished.store(true); } } setCursorPosition(NUM_THREADS, 0); std::cout << "Все потоки завершили работу." << std::endl; } int main() { SetConsoleCP(1251); SetConsoleOutputCP(1251); for (int i = 0; i < NUM_THREADS; ++i) { states[i].id = i; states[i].progress = 0; states[i].finished = false; states[i].has_error = false; } std::vector<std::thread> threads; for (int i = 0; i < NUM_THREADS; ++i) { threads.emplace_back(workerThread, i); } renderProgress(); for (auto& t : threads) { if (t.joinable()) { t.join(); } } std::cout << "Программа завершена." << std::endl; return 0; }