From a6118b5787c6dc82d5f738910c4f4e86e18a4918 Mon Sep 17 00:00:00 2001 From: pajjilykk Date: Tue, 28 Apr 2026 15:15:10 +0700 Subject: [PATCH] final cleanup 1 --- 1/exporter.py | 16 ++++++++++------ 1/main.cpp | 44 ++++++++++++++++++++++++++++---------------- 2 files changed, 38 insertions(+), 22 deletions(-) diff --git a/1/exporter.py b/1/exporter.py index 96fecc2..96e5411 100644 --- a/1/exporter.py +++ b/1/exporter.py @@ -94,19 +94,23 @@ def draw_gantt(ordered): first = min(p.start for p in ordered) + # Создаем карту цветов, чтобы PID всегда имел один и тот же цвет + cmap = plt.get_cmap('tab20') + color_map = {p.pid: cmap(i % 20) for i, p in enumerate(ordered)} + # ------------------------- # 1) TREE ORDER (current) # ------------------------- fig, ax = plt.subplots(figsize=(12, 6)) for i, p in enumerate(ordered): - ax.barh(i, p.duration, left=p.start - first, height=0.6) + ax.barh(i, p.duration, left=p.start - first, height=0.6, color=color_map[p.pid]) ax.text(p.start - first, i, f"PID {p.pid} ({p.depth})", va="center") ax.set_yticks(range(len(ordered))) ax.set_yticklabels([f"{p.pid} ({p.depth})" for p in ordered]) - ax.set_xlabel("Seconds from first process start") - ax.set_title("Gantt (Tree Order)") + ax.set_xlabel("Секунд с начала первого процесса") + ax.set_title("Диаграмма процессов (в виде дерева)") ax.invert_yaxis() plt.tight_layout() @@ -121,13 +125,13 @@ def draw_gantt(ordered): fig, ax = plt.subplots(figsize=(12, 6)) for i, p in enumerate(pid_order): - ax.barh(i, p.duration, left=p.start - first, height=0.6) + ax.barh(i, p.duration, left=p.start - first, height=0.6, color=color_map[p.pid]) ax.text(p.start - first, i, f"PID {p.pid} ({p.depth})", va="center") ax.set_yticks(range(len(pid_order))) ax.set_yticklabels([f"{p.pid} ({p.depth})" for p in pid_order]) - ax.set_xlabel("Seconds from first process start") - ax.set_title("Gantt (PID Order)") + ax.set_xlabel("Секунд с начала первого процесса") + ax.set_title("Диаграмма процессов (в порядке)") ax.invert_yaxis() plt.tight_layout() diff --git a/1/main.cpp b/1/main.cpp index a362cae..0875337 100644 --- a/1/main.cpp +++ b/1/main.cpp @@ -12,20 +12,21 @@ #include #include -constexpr int NIL = -1; -constexpr int MAX_PROCS = 1024; // Safety buffer for return values +constexpr int NIL = -1; // маркер пустого указателя +constexpr int MAX_PROCS = 1024; // лимит ячеек для результатов struct Node { int value; - int next; + int next; // индекс следующего узла }; struct SharedData { - int head; - int results[MAX_PROCS]; // Section for returning results in SHM - Node nodes[1]; + int head; // индекс начала списка + int results[MAX_PROCS]; // таблица для возврата индексов от потомков + Node nodes[1]; // массив узлов в памяти }; +// получение текущего времени для логов std::string now() { timeval tv{}; gettimeofday(&tv, nullptr); @@ -34,6 +35,7 @@ std::string now() { return oss.str(); } +// логирование старта процесса void log_start(int head, int depth) { std::cout << "PROC_START pid=" << getpid() << " ppid=" << getppid() @@ -44,6 +46,7 @@ void log_start(int head, int depth) { << '\n' << std::flush; } +// логирование завершения процесса void log_end(int head, int depth) { std::cout << "PROC_END pid=" << getpid() << " ppid=" << getppid() @@ -54,6 +57,7 @@ void log_end(int head, int depth) { << '\n' << std::flush; } +// слияние двух отсортированных списков int merge_lists(Node* pool, int left_head, int right_head) { if (left_head == NIL) return right_head; if (right_head == NIL) return left_head; @@ -61,6 +65,7 @@ int merge_lists(Node* pool, int left_head, int right_head) { int res_head = NIL; int tail = NIL; + // лямбда для добавления узла в хвост auto append = [&](int node_idx) { if (res_head == NIL) { res_head = node_idx; @@ -87,6 +92,7 @@ int merge_lists(Node* pool, int left_head, int right_head) { return res_head; } +// разделение списка пополам (черепаха и заяц) void split_list(Node* pool, int head, int& left, int& right) { if (head == NIL || pool[head].next == NIL) { left = head; @@ -104,9 +110,10 @@ void split_list(Node* pool, int head, int& left, int& right) { } left = head; right = pool[slow].next; - pool[slow].next = NIL; + pool[slow].next = NIL; // разрыв связи } +// обычная рекурсивная сортировка в одном процессе int local_list_sort(Node* pool, int head) { if (head == NIL || pool[head].next == NIL) return head; int left, right; @@ -116,7 +123,7 @@ int local_list_sort(Node* pool, int head) { return merge_lists(pool, left, right); } -// proc_idx helps each process find its unique slot in data->results +// параллельная сортировка через fork int parallel_list_sort(SharedData* data, int head, int depth, int max_depth, int proc_idx) { log_start(head, depth); @@ -125,6 +132,7 @@ int parallel_list_sort(SharedData* data, int head, int depth, int max_depth, int return head; } + // если глубина достигнута, сортируем локально if (depth >= max_depth) { int result = local_list_sort(data->nodes, head); log_end(result, depth); @@ -134,29 +142,29 @@ int parallel_list_sort(SharedData* data, int head, int depth, int max_depth, int int left_part, right_part; split_list(data->nodes, head, left_part, right_part); - // Calculate unique IDs for children in the results array + // индексы для записи результатов в массив shm int left_child_idx = 2 * proc_idx + 1; int right_child_idx = 2 * proc_idx + 2; pid_t pid_l = fork(); if (pid_l == 0) { int res = parallel_list_sort(data, left_part, depth + 1, max_depth, left_child_idx); - data->results[left_child_idx] = res; // Return result in SHM + data->results[left_child_idx] = res; // запись головы в общую память _exit(0); } pid_t pid_r = fork(); if (pid_r == 0) { int res = parallel_list_sort(data, right_part, depth + 1, max_depth, right_child_idx); - data->results[right_child_idx] = res; // Return result in SHM + data->results[right_child_idx] = res; // запись головы в общую память _exit(0); } - // Synchronize: Parent waits for both children to finish writing to SHM + // ждем завершения обоих детей waitpid(pid_l, nullptr, 0); waitpid(pid_r, nullptr, 0); - // Read results directly from Shared Memory + // читаем головы отсортированных частей из памяти int sorted_l = data->results[left_child_idx]; int sorted_r = data->results[right_child_idx]; @@ -165,31 +173,34 @@ int parallel_list_sort(SharedData* data, int head, int depth, int max_depth, int return final_head; } -int main(int argc, char* argv[]) { //main(data count, max recursion level) +int main(int argc, char* argv[]) { int n = 10000; int max_depth = 3; if (argc > 1) n = std::atoi(argv[1]); if (argc > 2) max_depth = std::atoi(argv[2]); + // создание сегмента разделяемой памяти size_t shm_size = sizeof(SharedData) + sizeof(Node) * (n - 1); int shmid = shmget(IPC_PRIVATE, shm_size, IPC_CREAT | 0666); SharedData* data = (SharedData*)shmat(shmid, nullptr, 0); - // Initialize return area + // зачистка таблицы результатов for(int i = 0; i < MAX_PROCS; ++i) data->results[i] = NIL; data->head = 0; std::mt19937 rng(time(0)); std::uniform_int_distribution dist(0, 999); + // заполнение списка случайными числами for (int i = 0; i < n; ++i) { data->nodes[i].value = dist(rng); data->nodes[i].next = (i == n - 1) ? NIL : i + 1; } - // Start with proc_idx 0 (the root) + // запуск параллельной сортировки (корень — индекс 0) data->head = parallel_list_sort(data, data->head, 0, max_depth, 0); + // вывод результата std::cout << "\nSorted list (first 20 elements): "; int curr = data->head; for(int i = 0; i < 20 && curr != NIL; ++i) { @@ -198,6 +209,7 @@ int main(int argc, char* argv[]) { //main(data count, max recursion level) } std::cout << std::endl; + // отсоединение и удаление памяти shmdt(data); shmctl(shmid, IPC_RMID, nullptr); return 0;