Основы программирования в Linux
Основы программирования в Linux читать книгу онлайн
Внимание! Книга может содержать контент только для совершеннолетних. Для несовершеннолетних чтение данного контента СТРОГО ЗАПРЕЩЕНО! Если в книге присутствует наличие пропаганды ЛГБТ и другого, запрещенного контента - просьба написать на почту [email protected] для удаления материала
<i> memset(buffer, ' ', sizeof(buffer));</i><i> printf("Process %d opening FIFO O_RDONLYn", getpid());</i><i> pipe_fd = open(FIFO_NAME, open_mode); </i><i> printf("Prосеss %d result %dn", getpid(), pipe_fd);</i><i> if (pipe_fd != -1) {</i><i> do {</i><i> res = read(pipe_fd, buffer,BUFFER_SIZE);</i><i> bytes_read += res;</i><i> } while (res > 0);</i><i> (void)close(pipe_fd);</i><i> } else {</i><i> exit(EXIT_FAILURE);</i><i> }</i><i> printf("Process %d finished, %d bytes readn", getpid(), bytes_read);</i> exit(EXIT_SUCCESS);}Когда вы выполните эти программы одновременно, с использованием команды
time$ <b>./fifo3 &</b>[1] 375Process 375 opening FIFO O_WRONLY$ <b>time ./fifo4</b>Process 377 opening FIFO O_RDONLYProcess 375 result 3Process 377 result 3Process 375 finishedProcess 377 finished, 10485760 bytes readreal 0m0.053suser 0m0.020ssys 0m0.040s[1]+ Done ./fifo3Как это работает
Обе программы применяют FIFO в режиме блокировки. Вы запускаете первой программу fifo3 (пишущий процесс/поставщик), которая блокируется, ожидая, когда читающий процесс откроет канал FIFO. Когда программа fifo4 (потребитель) запускается, пишущий процесс разблокируется и начинает записывать данные в канал. В это же время читающий процесс начинает считывать данные из канала.
ОС Linux так организует планирование двух процессов, что они оба выполняются, когда могут, и заблокированы в противном случае. Следовательно, пишущий процесс блокируется, когда канал полон, а читающий — когда канал пуст.
Вывод команды
timeБолее сложная тема: применение каналов FIFO в клиент-серверных приложениях
Заканчивая обсуждение каналов FIFO, давайте рассмотрим возможность построения очень простого клиент-серверного приложения, применяющего именованные каналы. Вы хотите, чтобы один серверный процесс принимал запросы, обрабатывал их и возвращал результирующие данные запрашивающей стороне — клиенту.
Вам нужно разрешить множественным клиентским процессам отправлять данные серверу. Для простоты предположим, что данные, которые нужно обработать, можно разбить на блоки, каждый из которых меньше
PIPE_BUFПоскольку сервер будет обрабатывать только один блок данных в каждый момент времени, кажется логичным создать один канал FIFO, который читается сервером и в который записывают всё клиенты. Если открыть FIFO в блокирующем режиме, сервер и клиенты будут при необходимости блокироваться.
Возвращать обработанные данные клиентам немного сложнее. Вам придется организовать второй канал для возвращаемых данных, один для каждого клиента. Если передавать идентификатор (PID) процесса-клиента в исходных данных, отправляемых на сервер, обе стороны смогут использовать его для генерации уникального имени канала с возвращаемыми данными.
Выполните упражнение 13.13.
1. Прежде всего, вам нужен заголовочный файл client.h, в котором определены данные, общие для серверных и клиентских программ. В приложение также для удобства включены требуемые системные заголовочные файлы.
#include <unistd.h>#include <stdlib.h>#include <stdio.h>#include <string.h>#include <fcntl.h>#include <limits.h>#include <sys/types.h>#include <sys/stat.h>#define SERVER_FIFO_NAME "/tmp/serv_fifo"#define CLIENT_FIFO_NAME "/tmp/cli_%d_fifo"#define BUFFER_SIZE 20struct data_to_pass_st { pid_t client_pid; char some_data[BUFFER_SIZE - 1];};2. Теперь займемся серверной программой server.c. В этом разделе вы создаете и затем открываете канал сервера. Он задается в режиме "только для чтения" и с блокировкой. После засыпания (из демонстрационных соображений) сервер читает данные от клиента, у которого есть структура типа
data_to_pass_st#include "client.h"#include <ctype.h>int main() { int server_fifo_fd, client fifo_fd; struct data_to_pass_st my_data; int read_res; char client_fifo[256]; char *tmp_char_ptr; mkfifo(SERVER_FIFO_NAME, 0777); server_fifo_fd = open(SERVER_FIFO_NAME, O_RDONLY);
