Книга: UNIX: взаимодействие процессов

Пример: неродственные клиент и сервер

Пример: неродственные клиент и сервер

В листинге 4.6 клиент и сервер все еще являлись родственными процессами. Переделаем этот пример так, чтобы родство между ними отсутствовало. В листинге 4.7 приведен текст программы-сервера. Текст практически идентичен той части программы из листинга 4.6, которая относилась к серверу.

Содержимое заголовка fifо.h приведено в листинге 4.8. Этот файл определяет имена двух FIFO, которые должны быть известны как клиенту, так и серверу.

В листинге 4.9 приведен текст программы-клиента, которая не слишком отличается от части программы из листинга 4.6, относящейся к клиенту. Обратите внимание, что именно клиент, а не сервер удаляет канал FIFO по завершении работы, потому что последние операции с этим каналом выполняются им.

Листинг 4.7. Функция main независимого сервера

//pipe/server_main.c
1  #include "fifo.h"
2  void server(int, int);
3  int
4  main(int argc, char **argv)
5  {
6   int readfd, writefd;
7   /* создание двух FIFO. OK, если они существуют */
8   if ((mkfifo(FIF01, FILE_MODE) < 0) && (errno != EEXIST))
9    err_sys("can't create %s", FIF01);
10  if ((mkfifo(FIF02, FILE MODE) < 0) && (errno != EEXIST)) {
11   unlink(FIF01);
12   err_sys("can't create %s", FIF02);
13  }
14  readfd = Open(FIF01, O_RDONLY, 0);
15  writefd = Open(FIFO2, O_WRONLY, 0);
16  server(readfd, writefd);
17  exit(0);
18 }
 

Листинг 4.8. Заголовочный файл fifo.h, используемый и клиентом, и сервером

//pipe/fifo.h
1 #include "unpipc.h"
2 #define FIFO1 "/tmp/fifo.1"
3 #define FIFO2 "/tmp/fifo.2"

Листинг 4.9. Функция main независимого клиента

//pipe/client_main.c
1  #include "fifo.h"
2  void client(int, int);
3  int
4  main(int argc, char **argv)
5  {
6   int readfd, writefd;
7   writefd = Open(FIFO1, O_WRONLY, 0);
8   readfd = Open(FIFO2, O_RDONLY, 0);
9   client(readfd, writefd);
10  Close(readfd);
11  Close(writefd);
12  Unlink(FIFO1);
13  UnLink(FIFO2);
14  exit(0);
15 }

ПРИМЕЧАНИЕ

Для программных каналов и каналов FIFO ядро ведет подсчет числа открытых дескрипторов, относящихся к ним, поэтому безразлично, кто именно вызовет unlink — клиент или сервер. Хотя эта функция и удаляет файл из файловой системы, она не влияет на открытые в момент ее выполнения дескрипторы. Однако для других форм IPC, таких как очереди сообщений стандарта System V, счетчик отсутствует, и если сервер удалит очередь после записи в нее последнего сообщения, она может быть удалена еще до того, как клиент это сообщение считает.

Для запуска клиента и сервера запустите сервер в фоновом режиме:

% server_fifo &

а затем запустите клиент. Можно было сделать и по-другому: запускать только программу-клиент, которая запускала бы сервер с помощью fork и exec. Клиент мог бы передавать серверу имена FIFO в качестве аргументов командной строки в команде exec, вместо того чтобы обе программы считывали их из заголовка. Но в этом случае сервер являлся бы дочерним процессом и проще было бы обойтись программным каналом.

Оглавление книги


Генерация: 1.312. Запросов К БД/Cache: 3 / 1
поделиться
Вверх Вниз