Распространение сигнала не работает между дочерними процессами в многопроцессной программе CLinux

Ответить
Anonymous
 Распространение сигнала не работает между дочерними процессами в многопроцессной программе C

Сообщение 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;
}



Подробнее здесь: https://stackoverflow.com/questions/793 ... s-c-progra
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Linux»