Уильям Стивенс - UNIX: взаимодействие процессов
- Название:UNIX: взаимодействие процессов
- Автор:
- Жанр:
- Издательство:Питер
- Год:2003
- Город:Санкт-Петербург
- ISBN:5-318-00534-9
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Уильям Стивенс - UNIX: взаимодействие процессов краткое содержание
Книга написана известным экспертом по операционной системе UNIX и посвящена описанию одной из форм межпроцессного взаимодействия, IPC, с использованием которой создается большинство сложных программ. В ней описываются четыре возможности разделения решаемых задач между несколькими процессами или потоками одного процесса: передача сообщений, синхронизация, разделяемая память, удаленный вызов процедур.
Книга содержит большое количество иллюстрирующих примеров и может использоваться как учебник по IPC, и как справочник для опытных программистов.
UNIX: взаимодействие процессов - читать онлайн бесплатно ознакомительный отрывок
Интервал:
Закладка:
Процесс может записать в очередь какие-то сообщения, после чего они могут быть получены другим процессом в любое время, даже если первый завершит свою работу. Мы говорим, что очереди сообщений обладают живучестью ядра (kernel persistence, раздел 1.3). Это также отличает их от программных каналов и FIFO. В главе 4 говорится о том, что данные, остающиеся в именованном или неименованном канале, сбрасываются, после того как все процессы закроют его.
В этой главе рассматриваются очереди сообщений стандарта Posix, а в главе 6 — стандарта System V. Функции для работы с ними во многом схожи, а главные отличия заключаются в следующем:
■ операция считывания из очереди сообщений Posix всегда возвращает самое старое сообщение с наивысшим приоритетом, тогда как из очереди System V можно считать сообщение с произвольно указанным приоритетом;
■ очереди сообщений Posix позволяют отправить сигнал или запустить программный поток при помещении сообщения в пустую очередь, тогда как для очередей System V ничего подобного не предусматривается.
Каждое сообщение в очереди состоит из следующих частей:
■ приоритет (беззнаковое целое, Posix) либо тип сообщения (целое типа long, System V);
■ длина полезной части сообщения, которая может быть нулевой;
■ собственно данные (если длина сообщения отлична от 0).
Этим очереди сообщений отличаются от программных каналов и FIFO. Последние две части сообщения представляют собой байтовые потоки, в которых отсутствуют границы между сообщениями и никак не указывается их тип. Мы обсуждали этот вопрос в разделе 4.10 и добавили свой собственный интерфейс для пересылки сообщений по программным каналам и FIFO. На рис. 5.1 показан возможный вид очереди сообщений.
Рис. 5.1. Очередь сообщений Posix, содержащая три сообщения
Мы предполагаем реализацию через связный список, причем его заголовок содержит два атрибута очереди: максимально допустимое количество сообщений в ней и максимальный размер сообщения. Об этих атрибутах мы расскажем более подробно в разделе 5.3.
В этой главе мы используем метод, к которому будем прибегать и в дальнейшем, рассматривая очереди сообщений, семафоры и разделяемую память. Поскольку все эти объекты IPC обладают по крайней мере живучестью ядра (вспомните раздел 1.3), мы можем писать небольшие программы, использующие эти методы для экспериментирования с ними и получения большей информации о том, как они работают. Например, мы можем написать программу, создающую очередь сообщений Posix, а потом написать другую программу, которая помещает сообщение в такую очередь, а потом еще одну, которая будет считывать сообщения из очереди. Помещая в очередь сообщения с различным приоритетом, мы увидим, в каком порядке они будут возвращаться функцией mq_receive.
5.2. Функции mq_open, mq_close, mq_unlink
Функция mq_open создает новую очередь сообщений либо открывает существующую:
#include
mqd_t mq_open(const char *name, int oflag, …
/* mode_t mode, struct mq_attr *attr */ );
/* Возвращает дескриптор очереди в случае успешного завершения;
–1 – в противном случае. */
Требования к аргументу пате описаны в разделе 2.2.
Аргумент oflag может принимать одно из следующих значений: O_RDONLY, O_WRONLY, O_RDWR в сочетании (логическое сложение) с O_CREAT, O_EXCL, O_NONBLOCK. Все эти флаги описаны в разделе 2.3.
При создании новой очереди (указан флаг O_CREAT и очередь сообщений еще не существует) требуется указание аргументов mode и attr. Возможные значения аргумента mode приведены в табл. 2.3. Аргумент attr позволяет задать некоторые атрибуты очереди. Если в качестве этого аргумента задать нулевой указатель, очередь будет создана с атрибутами по умолчанию. Эти атрибуты описаны в разделе 5.3.
Возвращаемое функцией mq_open значение называется дескриптором очереди сообщений, но оно не обязательно должно быть (и, скорее всего, не является) небольшим целым числом, как дескриптор файла или программного сокета. Это значение используется в качестве первого аргумента оставшихся семи функций для работы с очередями сообщений.
ПРИМЕЧАНИЕ
В системе Solaris 2.6 тип mqd_t определен как void*, а в Digital Unix 4.0B — как int. В нашем примере в разделе 5.8 эти дескрипторы трактуются как указатели на структуру. Название «дескриптор» было дано им по ошибке.
Открытая очередь сообщений закрывается функцией mq_close:
#include
int mq_close(mqd_t mqdes );
/*Возвращает 0 в случае успешного завершения. –1 в случае ошибки */
По действию эта функция аналогична close для открытого файла: вызвавший функцию процесс больше не может использовать дескриптор, но очередь сообщений из системы не удаляется. При завершении процесса все открытые очереди сообщений закрываются, как если бы для каждой был сделан вызов mq_close.
Для удаления из системы имени ( пате), которое использовалось в качестве аргумента при вызове mq_open, нужно использовать функцию mq_unlink:
#include
int mq_unlink(const char *name );
/* Возвращает 0 в случае успешного завершения. –1 в случае ошибки */
Для очереди сообщений (как и для файла) ведется подсчет числа процессов, в которых она открыта в данный момент, и по действию эта функция аналогична unlink для файла: имя (пате) может быть удалено из системы, даже пока число подключений к очереди отлично от нуля, но удаление очереди (в отличие от удаления имени из системы) не будет осуществлено до того, как очередь будет закрыта последним использовавшим ее процессом.
Очереди сообщений Posix обладают по меньшей мере живучестью ядра (раздел 1.3), то есть они продолжают существовать, храня все имеющиеся в них сообщения, даже если нет процессов, в которых они были бы открыты. Очередь существует, пока она не будет удалена явно с помощью mq_unlink.
ПРИМЕЧАНИЕ
Мы увидим, что если очередь сообщений реализована через отображаемые в память файлы (раздел 12.2), она может обладать живучестью файловой системы, но это не является обязательным и рассчитывать на это нельзя.
Пример: программа mqcreate1
Поскольку очереди сообщений Posix обладают по крайней мере живучестью ядра, можно написать набор небольших программ для работы с ними — с этими программами будет проще экспериментировать. Программа из листинга 5.1 [1] Все исходные тексты, опубликованные в этой книге, вы можете найти по адресу http://www.piter.com/download.
создает очередь сообщений, имя которой принимается в качестве аргумента командной строки.
//pxmsg/mqcreate1.с
1 #include "unpipc.h"
2 int
3 main(int argc, char **argv)
4 {
5 int с flags:
6 mqd_t mqd;
7 flags = O_RDWR | O_CREAT;
8 while ((c = Getopt(argc, argv, "e")) != –1) {
Интервал:
Закладка: