Доброго времени суток. Стоит задача по реализации программы с разделением на процессы, использующих в качестве средства взаимодействия именованные каналы. Краткое описание задачи: Родитель передает три строки, потомок возвращает самую короткую из них.
#include <pthread.h>
#include <signal.h>
#include <string.h>
#include <stdio.h>
#include <sys/types.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#define FIFO_NAME "my_fifo"
void hdl(int sig) {
if(sig == SIGUSR1)
printf("SIGUSR1...\n");
else if(sig == SIGUSR2)
printf("SIGUSR2...\n");
else
printf("Something else\n");
}
int main() {
struct sigaction act;
memset(&act, 0, sizeof(act));
act.sa_handler = hdl;
sigset_t set;
sigemptyset(&set);
sigaddset(&set, SIGUSR1);
sigaddset(&set, SIGUSR2);
act.sa_mask = set;
sigaction(SIGUSR1, &act, 0);
sigaction(SIGUSR2, &act, 0);
signal(SIGUSR1, hdl);
int sig;
pid_t pid;
char str1[100], str2[100], str3[100];
char shortest[100];
int fd_fifo; /* дескриптор FIFO */
/* Если файл с таким именем существует, удалим его */
unlink(FIFO_NAME);
/* Обнуляем маску прав */
(void)umask(0);
/* Создаем FIFO */
if ((mkfifo(FIFO_NAME, 0666)) == -1) {
perror("Невозможно создать fifo\n");
exit(0);
}
pid=fork();
if (pid>0) {
printf("parent...\n");
printf("Pid = %d\n",getpid() );
printf("Введите первую строку: ");
fgets(str1, sizeof(str1), stdin);
printf("Введите вторую строку: ");
fgets(str2, sizeof(str2), stdin);
printf("Введите третью строку: ");
fgets(str3, sizeof(str3), stdin);
/* Открываем fifo для чтения и записи */
if ((fd_fifo = open(FIFO_NAME, O_RDWR)) == -1) {
perror("Невозможно открыть fifo\n");
exit(0);
}
/* Записываем в fifo */
//write(fd_fifo,buffer,strlen(buffer)) ;
write(fd_fifo, str1, strlen(str1) + 1);
write(fd_fifo, str2, strlen(str2) + 1);
write(fd_fifo, str3, strlen(str3) + 1);
close(fd_fifo);
//посылаем сигнал дочернему процессу
kill(pid, SIGUSR1);
sigemptyset(&set);
sigaddset(&set, SIGUSR2);
printf("parent wait signal...\n");
//ожидаем сигнал SIGUSR1
sigwait(&set, &sig);
printf("parent exit...\n");
/* Открываем fifo для чтения и записи */
if ((fd_fifo = open(FIFO_NAME, O_RDWR|O_NONBLOCK)) == -1) {
perror("Невозможно открыть fifo\n");
exit(0);
}
// Читаем самую короткую строку от дочернего процесса
read(fd_fifo, shortest, sizeof(shortest));
printf("Родитель получил от потомка самую короткую строку: %s\n", shortest);
close(fd_fifo);
}
else if (pid==0){ //дочерний процесс
sigemptyset(&set);
sigaddset(&set, SIGUSR1);
//ожидаем сигнал SIGUSR1
sigwait(&set, &sig);
printf("child...\n");
printf("Pid = %d\n",getpid() );
printf("work...\n");
/* Открываем fifo для чтения и записи */
if ((fd_fifo = open(FIFO_NAME, O_RDWR)) == -1) {
perror("Невозможно открыть fifo\n");
exit(0);
}
// Чтение строк от родителя
if(read(fd_fifo, str1, sizeof(str1)) == -1)
perror("Невозможно прочесть str1 из FIFO\n");
if(read(fd_fifo, str2, sizeof(str2)) == -1)
perror("Невозможно прочесть str2 из FIFO\n");
if(read(fd_fifo, str3, sizeof(str3)) == -1)
perror("Невозможно прочесть str3 из FIFO\n");
close(fd_fifo);
printf("Дочерний процесс получил три строки от родителя.\n");
printf("%s\n, %s\n, %s\n", str1, str2, str3);
// Находим самую короткую строку
strcpy(shortest, str1);
if (strlen(str2) < strlen(shortest)) {
strcpy(shortest, str2);
}
if (strlen(str3) < strlen(shortest)) {
strcpy(shortest, str3);
}
printf("Дочерний процесс вычислил самую короткую строку: %s\n", shortest);
/*открываем fifo для чтения и записи */
if ((fd_fifo = open(FIFO_NAME, O_RDWR)) == -1) {
perror("Невозможно открыть fifo\n");
exit(0);
}
// Записываем самую короткую строку в FIFO
write(fd_fifo, shortest, strlen(shortest) + 1);
printf("Дочерний процесс отправил родителю самую короткую строку: %s\n", shortest);
close(fd_fifo);
sleep(5);
//посылаем сигнал родительскому процессу
kill(getppid(), SIGUSR2);
printf("child exit...\n");
exit(0);
}
return 0;
}
программа зависает на моменте открытия FIFO в дочернем процессе, но ошибку при этом не выдает
parent...
Pid = 13172
Введите первую строку: a
Введите вторую строку: aa
Введите третью строку: aaa
parent wait signal...
child...
Pid = 13173
work...