working #3 for kiri

This commit is contained in:
2025-10-23 20:06:09 +07:00
parent e5e1c10b24
commit cc842e52c6
10 changed files with 301 additions and 550 deletions

117
lab_3/kirill/parent.c Normal file
View File

@@ -0,0 +1,117 @@
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <string.h>
#include <errno.h>
int main(int argc, char *argv[]) {
// Проверка аргументов командной строки
if (argc < 4) {
const char *usage =
"Usage: parent <max_replacements> <input1.txt> <output1.txt> "
"[<input2.txt> <output2.txt> ...]\n"
" max_replacements: максимальное количество замен\n"
" input/output: пары входных и выходных файлов\n";
fprintf(stderr, "%s", usage);
return -1;
}
// Проверка четности количества файлов (пары input/output)
if ((argc - 2) % 2 != 0) {
fprintf(stderr, "Error: количество файлов должно быть четным (пары input/output)\n");
return -1;
}
const char *max_replacements_arg = argv[1];
int num_files = (argc - 2) / 2; // количество пар файлов
printf("Родительский процесс: PID=%d\n", getpid());
printf("Будет запущено %d дочерних процессов\n", num_files);
printf("Максимальное количество замен: %s\n\n", max_replacements_arg);
// Массив для хранения PID дочерних процессов
pid_t *child_pids = malloc(num_files * sizeof(pid_t));
if (child_pids == NULL) {
perror("malloc failed");
return -1;
}
// Запуск дочерних процессов
for (int i = 0; i < num_files; i++) {
const char *input_file = argv[2 + i * 2];
const char *output_file = argv[2 + i * 2 + 1];
pid_t pid = fork();
if (pid < 0) {
// Ошибка при создании процесса
perror("fork failed");
// Ждем завершения уже запущенных процессов
for (int j = 0; j < i; j++) {
int status;
waitpid(child_pids[j], &status, 0);
}
free(child_pids);
return -1;
} else if (pid == 0) {
// Код дочернего процесса
printf("Дочерний процесс %d: PID=%d, обработка %s -> %s\n",
i + 1, getpid(), input_file, output_file);
// Запуск программы из лабораторной работы №1
execl("./task18", "task18", input_file, output_file, max_replacements_arg, (char *)NULL);
// Если execl вернул управление, произошла ошибка
fprintf(stderr, "Дочерний процесс %d: execl failed для %s: %s\n",
i + 1, input_file, strerror(errno));
_exit(-1);
} else {
// Код родительского процесса
child_pids[i] = pid;
}
}
// Ожидание завершения всех дочерних процессов
printf("\nРодительский процесс ожидает завершения дочерних процессов...\n\n");
for (int i = 0; i < num_files; i++) {
int status;
pid_t terminated_pid = waitpid(child_pids[i], &status, 0);
if (terminated_pid < 0) {
perror("waitpid failed");
continue;
}
// Проверка статуса завершения
if (WIFEXITED(status)) {
int exit_code = WEXITSTATUS(status);
printf("Процесс %d (PID=%d) завершился нормально\n",
i + 1, terminated_pid);
if (exit_code == 0) {
printf(" Код завершения: %d (успех)\n", exit_code);
} else {
printf(" Код завершения: %d (ошибка)\n", exit_code);
}
} else if (WIFSIGNALED(status)) {
int signal = WTERMSIG(status);
printf("Процесс %d (PID=%d) был прерван сигналом %d\n",
i + 1, terminated_pid, signal);
} else {
printf("Процесс %d (PID=%d) завершился с неизвестным статусом\n",
i + 1, terminated_pid);
}
}
printf("\nВсе дочерние процессы завершены\n");
free(child_pids);
return 0;
}