Files
CS-LABS/mine/lab_3/parent.c
2025-12-10 16:50:28 +07:00

156 lines
6.4 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// parent.c - Родительская программа для лабораторной работы №3
// Запускает программу lab1_var12 в нескольких дочерних процессах
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <string.h>
#include <errno.h>
#define MAX_PROCESSES 100
// Структура для хранения информации о дочернем процессе
typedef struct {
pid_t pid;
char *input_file;
char *output_file;
} ChildInfo;
void print_usage(const char *progname) {
fprintf(stderr, "Usage: %s <lab1_program> <max_replacements> <input1> <output1> [<input2> <output2> ...]\n", progname);
fprintf(stderr, "Example: %s ./lab1_var12 5 in1.txt out1.txt in2.txt out2.txt\n", progname);
}
int main(int argc, char *argv[]) {
// Проверка минимального количества аргументов
// Формат: parent <программа> <max_repl> <input1> <output1> [<input2> <output2> ...]
if (argc < 5 || (argc - 3) % 2 != 0) {
fprintf(stderr, "ERROR: Недостаточное или неверное количество аргументов\n");
print_usage(argv[0]);
return 1;
}
const char *lab1_program = argv[1];
const char *max_replacements = argv[2];
// Вычисляем количество пар (input, output)
int num_files = (argc - 3) / 2;
if (num_files > MAX_PROCESSES) {
fprintf(stderr, "ERROR: Слишком много файлов (максимум %d пар)\n", MAX_PROCESSES);
return 1;
}
printf("=== Запуск родительского процесса ===\n");
printf("Родительский PID: %d\n", getpid());
printf("Программа для запуска: %s\n", lab1_program);
printf("Максимум замен: %s\n", max_replacements);
printf("Количество файловых пар: %d\n\n", num_files);
// Массив для хранения информации о дочерних процессах
ChildInfo children[MAX_PROCESSES];
int created_count = 0;
// Создаем дочерние процессы
for (int i = 0; i < num_files; i++) {
char *input_file = argv[3 + i * 2];
char *output_file = argv[3 + i * 2 + 1];
printf("Создание процесса %d для файлов: %s -> %s\n", i + 1, input_file, output_file);
pid_t pid = fork();
if (pid < 0) {
// Ошибка при создании процесса
fprintf(stderr, "ERROR: Не удалось создать дочерний процесс для %s: %s\n",
input_file, strerror(errno));
continue; // Продолжаем создавать остальные процессы
}
else if (pid == 0) {
// Дочерний процесс
printf(" -> Дочерний процесс PID=%d запускает обработку %s\n",
getpid(), input_file);
// Запускаем программу lab1_var12 с аргументами
execl(lab1_program, lab1_program, input_file, output_file, max_replacements, NULL);
// Если execl вернул управление, значит произошла ошибка
fprintf(stderr, "ERROR: Не удалось запустить программу %s: %s\n",
lab1_program, strerror(errno));
_exit(-1);
}
else {
// Родительский процесс
children[created_count].pid = pid;
children[created_count].input_file = input_file;
children[created_count].output_file = output_file;
created_count++;
}
}
if (created_count == 0) {
fprintf(stderr, "ERROR: Ни один дочерний процесс не был создан\n");
return 1;
}
printf("\n=== Ожидание завершения дочерних процессов ===\n");
// Ожидаем завершения всех дочерних процессов
int success_count = 0;
int error_count = 0;
for (int i = 0; i < created_count; i++) {
int status;
pid_t finished_pid = waitpid(children[i].pid, &status, 0);
if (finished_pid < 0) {
fprintf(stderr, "ERROR: Ошибка при ожидании процесса PID=%d: %s\n",
children[i].pid, strerror(errno));
error_count++;
continue;
}
printf("\nПроцесс PID=%d завершен (%s -> %s)\n",
finished_pid, children[i].input_file, children[i].output_file);
if (WIFEXITED(status)) {
int exit_code = WEXITSTATUS(status);
printf(" Код завершения: %d\n", exit_code);
if (exit_code == 0) {
printf(" Статус: SUCCESS\n");
success_count++;
} else if (exit_code == 255 || exit_code == -1) {
printf(" Статус: ERROR (не удалось выполнить)\n");
error_count++;
} else {
printf(" Статус: ERROR\n");
error_count++;
}
}
else if (WIFSIGNALED(status)) {
int signal = WTERMSIG(status);
printf(" Процесс завершен сигналом: %d\n", signal);
printf(" Статус: ERROR (получен сигнал)\n");
error_count++;
}
else {
printf(" Статус: Неизвестный статус завершения\n");
error_count++;
}
}
printf("\n=== Итоговая статистика ===\n");
printf("Всего запущено процессов: %d\n", created_count);
printf("Успешно завершено: %d\n", success_count);
printf("Завершено с ошибкой: %d\n", error_count);
if (error_count > 0) {
printf("\nОБЩИЙ СТАТУС: Завершено с ошибками\n");
return 1;
} else {
printf("\nОБЩИЙ СТАТУС: Все процессы завершены успешно\n");
return 0;
}
}