Я работаю над программой на C, которая создает три процесса для чтения и обработки файла:
Процесс 1 читает файл построчно
Процесс 2 подсчитывает строки
Процесс 3 (основной процесс) поддерживает окончательный подсчет
Процессы взаимодействуют через каналы и также должны реагировать на сигналы (SIGUSR1, SIGUSR2, SIGCONT , SIGINT), которые необходимо передать между ними. Когда один процесс получает сигнал, он должен передать его другим процессам. Сигналы настраиваются следующим образом:
signal(SIGUSR1, handle_s1); // Завершение
signal(SIGUSR2, handle_s2); // Приостановка
signal(SIGCONT, handle_s3); // Возобновляем
signal(SIGINT, handle_s4); // Обработка сообщений
Когда сигнал отправляется любому процессу (кроме родительского), он не распространяется должным образом на другие процессы. Дочерние процессы (pid1 и pid2), похоже, неправильно обрабатывают сигналы, они выполняют действие сигнала только над собой.
Что я делаю неправильно в своей реализации распространения сигнала? Как я могу гарантировать, что сигналы правильно распространяются между всеми тремя процессами?
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define BUFFER_SIZE 1024
#define FIFO_1 "/tmp/fifo_1"
#define FIFO_2 "/tmp/fifo_2"
#define FIFO_3 "/tmp/fifo_3"
typedef struct {
int signal_type;
pid_t sender_pid;
char message[256];
int line_count;
} Message;
volatile sig_atomic_t is_suspended = 0;
volatile sig_atomic_t should_exit = 0;
time_t start_time;
pid_t pid1, pid2, pid3;
void propagate_signal(int sig, pid_t sender_pid) {
if (sender_pid == pid1) {
printf("Propagating signal from Process 1 (PID: %d) to Process 2 and Process 3\n", sender_pid);
kill(pid2, sig);
kill(pid3, sig);
} else if (sender_pid == pid2) {
printf("Propagating signal from Process 2 (PID: %d) to Process 1 and Process 3\n", sender_pid);
kill(pid1, sig);
kill(pid3, sig);
} else if (sender_pid == pid3) {
printf("Propagating signal from Process 3 (PID: %d) to Process 1 and Process 2\n", sender_pid);
kill(pid1, sig);
kill(pid2, sig);
}
}
void handle_s1(int sig) {
should_exit = 1;
printf("Process %d: Received termination signal (S1)\n", getpid());
propagate_signal(SIGUSR1, getpid());
}
void handle_s2(int sig) {
is_suspended = 1;
printf("Process %d: Received suspension signal (S2)\n", getpid());
propagate_signal(SIGUSR2, getpid());
}
void handle_s3(int sig) {
is_suspended = 0;
printf("Process %d: Received resume signal (S3)\n", getpid());
propagate_signal(SIGCONT, getpid());
}
void handle_s4(int sig) {
Message msg;
char fifo_path[20];
sprintf(fifo_path, "/tmp/fifo_%d", getpid());
int fifo_fd = open(fifo_path, O_RDONLY | O_NONBLOCK);
if (fifo_fd >= 0) {
if (read(fifo_fd, &msg, sizeof(msg)) > 0) {
printf("Process %d: Received message from process %d: %s\n",
getpid(), msg.sender_pid, msg.message);
propagate_signal(SIGINT, getpid());
if (msg.line_count > 0) {
printf("Line count information received: %d\n", msg.line_count);
}
}
close(fifo_fd);
}
}
void send_message_to_others(int signal_type, const char* msg, int line_count) {
Message message;
message.signal_type = signal_type;
message.sender_pid = getpid();
message.line_count = line_count;
strncpy(message.message, msg, 255);
for (int i = 1; i = 0) {
write(fd, &message, sizeof(message));
close(fd);
}
}
}
int main(int argc, char *argv[]) {
if (argc != 2) {
fprintf(stderr, "Usage: %s \n", argv[0]);
exit(1);
}
mkfifo(FIFO_1, 0666);
mkfifo(FIFO_2, 0666);
mkfifo(FIFO_3, 0666);
signal(SIGUSR1, handle_s1);
signal(SIGUSR2, handle_s2);
signal(SIGCONT, handle_s3);
signal(SIGINT, handle_s4);
int pipe1[2], pipe2[2];
start_time = time(NULL);
if (pipe(pipe1) == -1 || pipe(pipe2) == -1) {
perror("pipe");
exit(1);
}
pid1 = fork();
if (pid1 == 0) {
pid_t pid = getpid();
printf("Process 1 (PID: %d) started\n", pid);
close(pipe1[0]);
close(pipe2[0]);
close(pipe2[1]);
FILE *file = fopen(argv[1], "r");
if (file == NULL) {
perror("fopen");
exit(1);
}
char buffer[BUFFER_SIZE];
size_t bytes_read;
int line_number = 0;
while (fgets(buffer, BUFFER_SIZE, file) != NULL && !should_exit) {
while(is_suspended) {
usleep(100000);
}
bytes_read = strlen(buffer);
if (write(pipe1[1], buffer, bytes_read) != bytes_read) {
perror("write to pipe");
break;
}
line_number++;
printf("Process 1: Read line %d: %s", line_number, buffer);
send_message_to_others(4, "Read new line", line_number);
usleep(100000);
}
printf("Process 1: Finished reading file (read %d lines)\n", line_number);
fclose(file);
close(pipe1[1]);
exit(0);
}
pid2 = fork();
if (pid2 == 0) {
pid_t pid = getpid();
printf("Process 2 (PID: %d) started\n", pid);
close(pipe1[1]);
close(pipe2[0]);
char ch;
int line_count = 0;
ssize_t bytes_read;
int last_reported_count = 0;
while ((bytes_read = read(pipe1[0], &ch, 1)) > 0 && !should_exit) {
while(is_suspended) {
usleep(100000);
}
if (ch == '\n') {
line_count++;
if (line_count != last_reported_count) {
printf("Process 2: Counted line %d\n", line_count);
write(pipe2[1], &line_count, sizeof(line_count));
send_message_to_others(4, "Counted line", line_count);
last_reported_count = line_count;
}
}
}
printf("Process 2: Finishing operation\n");
close(pipe1[0]);
close(pipe2[1]);
exit(0);
}
pid3 = getpid();
printf("Process 3 (main, PID: %d) started\n", pid3);
close(pipe1[0]);
close(pipe1[1]);
close(pipe2[1]);
int last_count = 0;
int final_count;
while (read(pipe2[0], &final_count, sizeof(final_count)) > 0 && !should_exit) {
while(is_suspended) {
usleep(100000);
}
if (final_count != last_count) {
printf("Main process: Updated line count: %d\n", final_count);
send_message_to_others(4, "Updated line count", final_count);
last_count = final_count;
}
}
printf("Main process: Finishing operation. Final line count: %d\n", last_count);
waitpid(pid1, NULL, 0);
waitpid(pid2, NULL, 0);
close(pipe2[0]);
unlink(FIFO_1);
unlink(FIFO_2);
unlink(FIFO_3);
return 0;
}
Подробнее здесь: https://stackoverflow.com/questions/793 ... s-c-progra
Распространение сигнала не работает между дочерними процессами в многопроцессной программе C ⇐ Linux
1736277238
Anonymous
Я работаю над программой на C, которая создает три процесса для чтения и обработки файла:
Процесс 1 читает файл построчно
Процесс 2 подсчитывает строки
Процесс 3 (основной процесс) поддерживает окончательный подсчет
Процессы взаимодействуют через каналы и также должны реагировать на сигналы (SIGUSR1, SIGUSR2, SIGCONT , SIGINT), которые необходимо передать между ними. Когда один процесс получает сигнал, он должен передать его другим процессам. Сигналы настраиваются следующим образом:
signal(SIGUSR1, handle_s1); // Завершение
signal(SIGUSR2, handle_s2); // Приостановка
signal(SIGCONT, handle_s3); // Возобновляем
signal(SIGINT, handle_s4); // Обработка сообщений
Когда сигнал отправляется любому процессу (кроме родительского), он не распространяется должным образом на другие процессы. Дочерние процессы (pid1 и pid2), похоже, неправильно обрабатывают сигналы, они выполняют действие сигнала только над собой.
Что я делаю неправильно в своей реализации распространения сигнала? Как я могу гарантировать, что сигналы правильно распространяются между всеми тремя процессами?
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define BUFFER_SIZE 1024
#define FIFO_1 "/tmp/fifo_1"
#define FIFO_2 "/tmp/fifo_2"
#define FIFO_3 "/tmp/fifo_3"
typedef struct {
int signal_type;
pid_t sender_pid;
char message[256];
int line_count;
} Message;
volatile sig_atomic_t is_suspended = 0;
volatile sig_atomic_t should_exit = 0;
time_t start_time;
pid_t pid1, pid2, pid3;
void propagate_signal(int sig, pid_t sender_pid) {
if (sender_pid == pid1) {
printf("Propagating signal from Process 1 (PID: %d) to Process 2 and Process 3\n", sender_pid);
kill(pid2, sig);
kill(pid3, sig);
} else if (sender_pid == pid2) {
printf("Propagating signal from Process 2 (PID: %d) to Process 1 and Process 3\n", sender_pid);
kill(pid1, sig);
kill(pid3, sig);
} else if (sender_pid == pid3) {
printf("Propagating signal from Process 3 (PID: %d) to Process 1 and Process 2\n", sender_pid);
kill(pid1, sig);
kill(pid2, sig);
}
}
void handle_s1(int sig) {
should_exit = 1;
printf("Process %d: Received termination signal (S1)\n", getpid());
propagate_signal(SIGUSR1, getpid());
}
void handle_s2(int sig) {
is_suspended = 1;
printf("Process %d: Received suspension signal (S2)\n", getpid());
propagate_signal(SIGUSR2, getpid());
}
void handle_s3(int sig) {
is_suspended = 0;
printf("Process %d: Received resume signal (S3)\n", getpid());
propagate_signal(SIGCONT, getpid());
}
void handle_s4(int sig) {
Message msg;
char fifo_path[20];
sprintf(fifo_path, "/tmp/fifo_%d", getpid());
int fifo_fd = open(fifo_path, O_RDONLY | O_NONBLOCK);
if (fifo_fd >= 0) {
if (read(fifo_fd, &msg, sizeof(msg)) > 0) {
printf("Process %d: Received message from process %d: %s\n",
getpid(), msg.sender_pid, msg.message);
propagate_signal(SIGINT, getpid());
if (msg.line_count > 0) {
printf("Line count information received: %d\n", msg.line_count);
}
}
close(fifo_fd);
}
}
void send_message_to_others(int signal_type, const char* msg, int line_count) {
Message message;
message.signal_type = signal_type;
message.sender_pid = getpid();
message.line_count = line_count;
strncpy(message.message, msg, 255);
for (int i = 1; i = 0) {
write(fd, &message, sizeof(message));
close(fd);
}
}
}
int main(int argc, char *argv[]) {
if (argc != 2) {
fprintf(stderr, "Usage: %s \n", argv[0]);
exit(1);
}
mkfifo(FIFO_1, 0666);
mkfifo(FIFO_2, 0666);
mkfifo(FIFO_3, 0666);
signal(SIGUSR1, handle_s1);
signal(SIGUSR2, handle_s2);
signal(SIGCONT, handle_s3);
signal(SIGINT, handle_s4);
int pipe1[2], pipe2[2];
start_time = time(NULL);
if (pipe(pipe1) == -1 || pipe(pipe2) == -1) {
perror("pipe");
exit(1);
}
pid1 = fork();
if (pid1 == 0) {
pid_t pid = getpid();
printf("Process 1 (PID: %d) started\n", pid);
close(pipe1[0]);
close(pipe2[0]);
close(pipe2[1]);
FILE *file = fopen(argv[1], "r");
if (file == NULL) {
perror("fopen");
exit(1);
}
char buffer[BUFFER_SIZE];
size_t bytes_read;
int line_number = 0;
while (fgets(buffer, BUFFER_SIZE, file) != NULL && !should_exit) {
while(is_suspended) {
usleep(100000);
}
bytes_read = strlen(buffer);
if (write(pipe1[1], buffer, bytes_read) != bytes_read) {
perror("write to pipe");
break;
}
line_number++;
printf("Process 1: Read line %d: %s", line_number, buffer);
send_message_to_others(4, "Read new line", line_number);
usleep(100000);
}
printf("Process 1: Finished reading file (read %d lines)\n", line_number);
fclose(file);
close(pipe1[1]);
exit(0);
}
pid2 = fork();
if (pid2 == 0) {
pid_t pid = getpid();
printf("Process 2 (PID: %d) started\n", pid);
close(pipe1[1]);
close(pipe2[0]);
char ch;
int line_count = 0;
ssize_t bytes_read;
int last_reported_count = 0;
while ((bytes_read = read(pipe1[0], &ch, 1)) > 0 && !should_exit) {
while(is_suspended) {
usleep(100000);
}
if (ch == '\n') {
line_count++;
if (line_count != last_reported_count) {
printf("Process 2: Counted line %d\n", line_count);
write(pipe2[1], &line_count, sizeof(line_count));
send_message_to_others(4, "Counted line", line_count);
last_reported_count = line_count;
}
}
}
printf("Process 2: Finishing operation\n");
close(pipe1[0]);
close(pipe2[1]);
exit(0);
}
pid3 = getpid();
printf("Process 3 (main, PID: %d) started\n", pid3);
close(pipe1[0]);
close(pipe1[1]);
close(pipe2[1]);
int last_count = 0;
int final_count;
while (read(pipe2[0], &final_count, sizeof(final_count)) > 0 && !should_exit) {
while(is_suspended) {
usleep(100000);
}
if (final_count != last_count) {
printf("Main process: Updated line count: %d\n", final_count);
send_message_to_others(4, "Updated line count", final_count);
last_count = final_count;
}
}
printf("Main process: Finishing operation. Final line count: %d\n", last_count);
waitpid(pid1, NULL, 0);
waitpid(pid2, NULL, 0);
close(pipe2[0]);
unlink(FIFO_1);
unlink(FIFO_2);
unlink(FIFO_3);
return 0;
}
Подробнее здесь: [url]https://stackoverflow.com/questions/79337102/signal-propagation-not-working-between-child-processes-in-multi-process-c-progra[/url]
Ответить
1 сообщение
• Страница 1 из 1
Перейти
- Кемерово-IT
- ↳ Javascript
- ↳ C#
- ↳ JAVA
- ↳ Elasticsearch aggregation
- ↳ Python
- ↳ Php
- ↳ Android
- ↳ Html
- ↳ Jquery
- ↳ C++
- ↳ IOS
- ↳ CSS
- ↳ Excel
- ↳ Linux
- ↳ Apache
- ↳ MySql
- Детский мир
- Для души
- ↳ Музыкальные инструменты даром
- ↳ Печатная продукция даром
- Внешняя красота и здоровье
- ↳ Одежда и обувь для взрослых даром
- ↳ Товары для здоровья
- ↳ Физкультура и спорт
- Техника - даром!
- ↳ Автомобилистам
- ↳ Компьютерная техника
- ↳ Плиты: газовые и электрические
- ↳ Холодильники
- ↳ Стиральные машины
- ↳ Телевизоры
- ↳ Телефоны, смартфоны, плашеты
- ↳ Швейные машинки
- ↳ Прочая электроника и техника
- ↳ Фототехника
- Ремонт и интерьер
- ↳ Стройматериалы, инструмент
- ↳ Мебель и предметы интерьера даром
- ↳ Cантехника
- Другие темы
- ↳ Разное даром
- ↳ Давай меняться!
- ↳ Отдам\возьму за копеечку
- ↳ Работа и подработка в Кемерове
- ↳ Давай с тобой поговорим...
Мобильная версия