организовать двустороннюю поочередную связь процесса-родителя и процесса-ребенка через pipe, используя для синхронизации сигналы sigusr1 и sigusr2. |
Организация взаимодействия процессов через pipe и FIFO в UNIX
Системные вызовы read(), write(), close()
Для совершения потоковых операций чтения информации из файла и ее записи в файл применяются системные вызовы read() и write() .
Мы сейчас не акцентируем внимание на понятии указателя текущей позиции в файле и взаимном влиянии значения этого указателя и поведения системных вызовов. Этот вопрос будет обсуждаться в дальнейшем на семинарах 11–12.
После завершения потоковых операций процесс должен выполнить операцию закрытия потока ввода-вывода, во время которой произойдет окончательный сброс буферов на линии связи, освободятся выделенные ресурсы операционной системы, и элемент таблицы открытых файлов, соответствующий файловому дескриптору, будет отмечен как свободный. За эти действия отвечает системный вызов close() . Надо отметить, что при завершении работы процесса (см. семинар 3–4) с помощью явного или неявного вызова функции exit() происходит автоматическое закрытие всех открытых потоков ввода-вывода.
Прогон программы для записи информации в файл
Для иллюстрации сказанного давайте рассмотрим следующую программу:
/*Программа 05-1.с, иллюстрирующая использование системных вызовов open(), write() и close() для записи информации в файл */ #include <sys/types.h> #include <fcntl.h> #include <stdio.h> int main(){ int fd; size_t size; char string[] = "Hello, world!"; /* Обнуляем маску создания файлов текущего процесса для того, чтобы права доступа у создаваемого файла точно соответствовали параметру вызова open() */ (void)umask(0); /* Попытаемся открыть файл с именем myfile в текущей директории только для операций вывода. Если файла не существует, попробуем его создать с правами доступа 0666, т. е. read-write для всех категорий пользователей */ if((fd = open("myfile", O_WRONLY | O_CREAT, 0666)) < 0){ /* Если файл открыть не удалось, печатаем об этом сообщение и прекращаем работу */ printf("Can\'t open file\n"); exit(-1); } /* Пробуем записать в файл 14 байт из нашего массива, т.е. всю строку "Hello, world!" вместе с признаком конца строки */ size = write(fd, string, 14); if(size != 14){ /* Если записалось меньшее количество байт, сообщаем об ошибке */ printf("Can\'t write all string\n"); exit(-1); } /* Закрываем файл */ if(close(fd) < 0){ printf("Can\'t close file\n"); } return 0; }Листинг 5.1. Программа 05-1.с, иллюстрирующая использование системных вызовов open(), write() и close() для записи информации в файл
Наберите, откомпилируйте эту программу и запустите ее на исполнение. Обратите внимание на использование системного вызова umask() с параметром 0 для того, чтобы права доступа к созданному файлу точно соответствовали указанным в системном вызове open() .
Написание, компиляция и запуск программы для чтения информации из файла
Измените программу из предыдущего раздела так, чтобы она читала записанную ранее в файл информацию и печатала ее на экране. Все лишние операторы желательно удалить.