UNIX: взаимодействие процессов — страница 21 из 35

2. Переносимость (вспомните табл. 1.3). Практически все системы под управлением Unix поддерживают именованные и неименованные каналы и блокировку записей стандарта Posix. К 1998 году большинство систем поддерживало средства IPC System V (очереди сообщений, семафоры и разделяемую память), тогда как лишь немногие поддерживали те же средства стандарта Posix. Должны появиться новые реализации Posix IPC, но, к сожалению, эти средства не являются обязательными в стандарте Unix 98. Многие системы поддерживают потоки Posix (включая взаимные исключения и условные переменные) или станут поддерживать их в ближайшем будущем. Некоторые системы, поддерживающие потоки Posix, не воспринимают атрибут использования между процессами для взаимных исключений и условных переменных. Блокировки чтения-записи, требуемые стандартом Unix 98, должны вскоре войти в стандарт Posix, и множество систем уже поддерживают какой-либо из видов таких блокировок. Отображение в память распространено достаточно широко, и большинство Unix-систем поддерживают неименованное отображение (с использованием либо /dev/zero, либо MAP_ANON). Средства Sun RPC должны быть доступны практически на всех системах Unix, тогда как двери пока реализованы только в Solaris.

3. Производительность. Если для вашего приложения критична скорость работы средств IPC, воспользуйтесь программами из приложения А. Лучше всего изменить эти программы для имитации среды, в которой будет работать ваше приложение, и таким образом измерить скорость работы средств IPC в этой среде.

4. Планирование в реальном времени. Если вам нужно воспользоваться этой функцией и система ее поддерживает, рассмотрите возможность использования функций Posix для передачи сообщений и синхронизации (очереди сообщений, семафоры, взаимные исключения и условные переменные). Например, когда увеличиваются значения семафора, в вызове к которому заблокировано несколько потоков, разблокируемый поток выбирается в соответствии с политиками планирования и параметрами заблокированных потоков. Для семафоров System V это не гарантируется.

Чтобы помочь вам понять некоторые особенности и ограничения средств IPC, мы вкратце перечислим основные различия между ними:

■ Именованные и неименованные каналы представляют собой потоки байтов без грaниц между сообщениями. Очереди сообщений Posix и System V предусматривают наличие границ сообщений. Сравните это с протоколами Интернета: TCP — это поток байтов, a UDP — последовательность сообщений с явно определенными границами.

■ Очереди сообщений Posix могут отправлять процессу сигнал или запускать новый поток в случае, если в пустую очередь помещается сообщение. Для очередей System V такая возможность не предусматривается. Ни один из типов очередей сообщений не может быть использован непосредственно с вызовами select и poll (глава 6 [24]), хотя некие решения этой проблемы были приведены при обсуждении листинга 5.12 и в разделе 6.9.

■ Данные в именованных и неименованных каналах передаются в порядке очереди (FIFO). Очереди сообщений Posix и System V предусматривают возможность присваивания сообщениям различного приоритета. При чтении из очереди Posix всегда возвращается сообщение с наивысшим приоритетом. Для очередей System V можно указать любой конкретный тип сообщения.

■ При помещении сообщения в очередь Posix или System V или в именованный или неименованный канал ровно один экземпляр доставляется ровно одному считывающему потоку. Возможность передачи нескольким адресатам отсутствует (в отличие от сокетов и XTI при использовании протокола UDP — главы 18 и 19 [24]).

■ Взаимные исключения, условные переменные и блокировки чтения-записи имен не имеют. Они могут легко использоваться потоками одного процесса. Совместное использование их различными процессами возможно только в случае, если эти объекты располагаются в общей для этих процессов области памяти. Семафоры Posix бывают двух типов: именованные и размещаемые в памяти. Именованные семафоры могут использоваться только различными процессами (они идентифицируются именами Posix IPC), а размещаемые в памяти должны для этого находиться в разделяемой памяти. Семафоры System V также являются именованными (с помощью типа key_t), они также могут без проблем использоваться несколькими процессами совместно.

■ Блокировки записей fcntl автоматически снимаются ядром при завершении процесса, если он сам об этом не позаботится. Для семафоров System V эта возможность является дополнительной. Для взаимных исключений, условных переменных, блокировок чтения-записи и семафоров Posix эта возможность не предусматривается.

■ Каждая блокировка fcntl действует на некоторый диапазон байтов (называемый записью) в файле, указываемом с помощью дескриптора. Блокировки чтения-записи не связываются ни с какими записями.

■ Разделяемая память Posix и System V обладает живучестью ядра. Она существует до тех пор, пока не будет удалена явно, даже если в какой-то момент не используется ни одним процессом.

■ Размер объекта разделяемой памяти Posix может быть увеличен в процессе работы. Размер сегмента разделяемой памяти System V фиксируется при его создании.

■ Oгрaничeния ядра на три типа System V IPC часто требуют настройки вручную, поскольку устанавливаемые для них по умолчанию значения часто не соответствуют требованиям реальных приложений (раздел 3.8). Oгрaничeния на средства Posix IPC обычно не требуют настройки.

■ Информация об объектах System V IPC (текущий размер, идентификатор владельца, время последнего изменения и т. п.) возвращается вызовом одной из функций XXXctl с командой IPC_STAT и пpoгрaммoй ipcs. Для получения информации об объектах Posix стандартных способов не предусматривается. Если реализация использует файлы в качестве основы для этих объектов, можно получить эту информацию с помощью функции stat или программы ls, если нам известен способ преобразования имени Posix IPC в полное имя файла. Если же в данной реализации файлы не используются, способа получить такую информацию может и не существовать.

■ Из всех средств синхронизации — взаимных исключений, условных переменных, блокировок чтения-записи, блокировок записи, семафоров — только две функции можно вызывать из обработчика сигналов (табл. 5.1): sem_post и fcntl.

■ Из всех средств передачи сообщений — каналов, очередей сообщений Posix и System V — только две функции могут быть вызваны из обработчика сигналов: read и write (используются с именованными и неименованными каналами).

■ Из всех средств передачи сообщений только двери предоставляют серверу точную информацию о клиенте (раздел 15.5). В разделе 5.4 мы упомянули два других способа передачи сообщений, которые также предоставляют информацию о клиенте: доменные сокеты в BSD/OS (раздел 14.8 [24]) и каналы в SVR4, если по ним передается дескриптор файла (раздел 15.3.1 [21]).

ПРИЛОЖЕНИЕ АИзмерение производительности

А.1. Введение

В основной части книги мы перечислили шесть средств передачи сообщений:

■ неименованные каналы (pipes);

■ именованные каналы (FIFO);

■ очереди сообщений Posix;

■ очереди сообщений System V;

■ двери;

■ SunRPC.

Кроме того, мы указали пять типов средств синхронизации:

■ взаимные исключения и условные переменные;

■ блокировки чтения-записи;

■ блокировка записей fcntl;

■ семафоры Posix;

■ семафоры System V.

В этом приложении мы разработаем набор простых программ для измерения производительности этих видов IPC, чтобы иметь возможность аргументировать свой выбор одного из этих средств для конкретной задачи.

При сравнении средств передачи сообщений нас интересуют два параметра:

1. Полоса пропускания (bandwidth) — скорость передачи данных по каналу IPC. Для измерения этого параметра мы передаем огромное количество данных (миллионы байтов) от одного процесса другому. Этот параметр измеряется для различных объемов данных на операцию (например, write и read для каналов), и мы ожидаем, что полоса пропускания будет увеличиваться вместе с увеличением количества передаваемых за одну операцию данных.

2. Задержка (latency) определяется как время, которое требуется небольшому сообщению, чтобы проделать путь по каналу IPC от одного процесса к другому и обратно. Мы измеряем время задержки для сообщения размером 1 байт.

В реальности величина полосы пропускания говорит нам о том, сколько времени будет потрачено на передачу блока данных по каналу IPC, но IPC также используется и для передачи небольших управляющих сообщений. Задержка определяет время, необходимое для передачи этих сообщений. Важными оказываются обе величины.

Чтобы измерить скорость работы средств синхронизации, мы изменим программу, увеличивающую значение счетчика в разделяемой памяти. Поскольку увеличение элементарная операция, время будет тратиться в основном на работу средств синхронизации.

ПРИМЕЧАНИЕ

Программы этого приложения, используемые для измерения производительности средств IPC, основаны на пакете lmbench [15]. Этот пакет содержит набор тестов, измеряющих множество параметров системы (скорость переключения контекста и т. п.), а не только производительность средств IPC. Исходный код пакета доступен по адресу http://www.bitmover.com/lmbench.

Величины, приведенные в этом приложении, дают нам возможность сравнить методы, описанные в книге. Заодно мы хотели показать, как просто измерить эти величины. Прежде чем останавливать свой выбор на одном из средств IPC, нелишне было бы получить эти значения в вашей собственной системе. К сожалению, насколько легко измерить величины, настолько же трудно объяснить аномальное их поведение в отсутствие доступа к исходному коду ядра и библиотек.

А.2. Результаты

Сведем вместе результаты, полученные в этом приложении. Данный раздел может использоваться как справочник при чтении книги.

Для проведения измерений использовались две системы: SparcStation 4/110 под управлением Solaris 2.6 и Digital Alpha (DEC 3000 model 300, Pelican) под управлением Digital Unix 4.0В. В файл /etc/system системы Solaris 2.6 были добавлены следующие строки:

set msgsys:msginfo_msgmax = 16384

set msgsys:msginfo_msgmnb = 32768

set msgsys:msginfo_msgseg = 4096

Это дает возможность отправлять сообщения размером 16384 байт в очередь сообщений System V (табл. А.2). Те же изменения осуществляются в Digital Unix 4.0B введением следующих строк с помощью программы sysconfig:

ipc:

 msg-max = 16384

 msg-mnb = 32768

Результаты измерения полосы пропускания сообщений

В табл. А.2 приведены результаты измерений на компьютере Sparc под управлением Solaris 2.6, а на рис. А.1 — график этих результатов.

Как мы и предполагали, полоса пропускания увеличивается с размером сообщения. Поскольку во многих реализациях очередей сообщений System V ограничение на размер сообщения, установленное в ядре, достаточно мало (раздел 3.8), максимальный размер сообщения в нашей программе имеет значение 16384 байт. 

Уменьшение полосы для сообщений размером около 4096 байт в Solaris 2.6, возможно, связано с настройкой внутренних ограничений ядра. Для сравнения с [24] мы приводим результаты аналогичных измерений для сокета TCP и доменного сокета Unix. Эти две величины были получены с помощью программ пакета lmbench для сообщений размером 65536 байт. При измерении быстродействия сокета TCP оба процесса выполнялись на одном узле.

Результаты измерения задержки

В табл. А.1 приведены значения задержки в Solaris 2.6 и Digital Unix 4.0B.


Таблица А.1. Задержка при передаче сообщения размером 1 байт (в микросекундах) 

КаналОчередь сообщений PosixОчередь сообщений System VДвериSun RPC TCPSun RPC UDPСокет TCPСокет UDPДоменный сокет
Solaris 2.632458426012118911677798755465
DUnix 4.0B57499562516481373848639289 

Рис. А.1. Полоса пропускания средств передачи сообщений в Solaris 2.6.


В разделе A.4 мы приведем листинги программ, использованных для получения первых четырех величин, а оставшиеся три получены с помощью пакета lmbench. При измерении скорости работы TCP и UDP оба процесса находились на одном узле. 


Таблица А.2. Полоса пропускания для разных типов сообщений в Solaris 2.6 (Мбайт/с)

Размер сообщенияКаналОчередь сообщений PosixОчередь сообщений System VДвериSun RPC TCPSun RPC UDPСокет TCPДоменный сокет
10246,33,74,96,30,50,5
20488,75,36,310,00,91,0
40969,88,46,612,61,62,8
819212,710,25,814,42,42,8
1638413,111,66,116,83,23,4
3276813,213,411,43,54,3
6553613,714,412,23,713,211,3

Рис. А.2. Полоса пропускания для различных средств передачи сообщений (Digital Unix 4.0B)


Таблица А.З. Полоса пропускания для различных типов сообщения в Digital Unix 4.0B (Мбайт/с)

Размер сообщенияКаналОчередь сообщений PosixОчередь сообщений System VSun RPC TCPSun RPC UDPСокет TCPДоменный сокет
10249,91,812,70,60,6
204815,23,515,00,81,0
409617,15,921,11,31,8
819216,58,617,11,82,5
1638417,311,717,32,3
3276815,914,02,6
6553614,29,42,84,618,0

Результаты синхронизации потоков

В табл. А.4 приведены значения времени, нужного одному или нескольким потокам для увеличения счетчика в разделяемой памяти с использованием различных средств синхронизации в Solaris 2.6, а на рис. А.3 показан график этих значений. Каждый поток увеличивает значение счетчика 1000000 раз, а количество потоков меняется от 1 до 5. В табл. А.5 приведены эти же значения для Digital Unix 4.0В, а на рис. А.4 — график этих значений. 

Рис. А.З. Время увеличения счетчика в разделяемой памяти (Solaris 2.6)


Мы увеличиваем количество потоков, чтобы проверить правильность кода. Кроме того, при добавлении потоков время работы программы может начать расти нелинейно. Блокировка fcntl может использоваться только одним потоком, поскольку эта форма синхронизации предназначена только для использования между несколькими процессами, а не потоками одного процесса. 

В Digital Unix 4.0B значения для семафоров Posix оказываются непомерно большими, если работает более одного потока, что указывает на наличие какой-то аномалии. На графике мы эти значения не приводим.

ПРИМЕЧАНИЕ

Одна из возможных причин этой аномалии заключается в том, что в этой программе синхронизация проверяется неправильно. В данном случае потоки не делают ничего полезного, и все время уходит на синхронизацию. Поскольку потоки создаются с внутрипроцессной конкуренцией, при потере управления потоком блокировка сохраняется, поэтому поток, получающий управление, выполняться дальше не может. 

Рис.А.4. Время увеличения счетчика в разделяемой памяти (Digital Unix 4.0B)


Таблица А.4. Время увеличения счетчика в разделяемой памяти для Solaris 2.6 (в секундах)

Кол-во потоковВзаимное исключение PosixБлокировка чтения-записиСемафор Posix в памятиИменованный семафор PosixСемафор System VСемафор System V с UNDOБлокировка записей fcntl
10,72,04,515,416,321,189,4
21,55,49,031,131,537,5
32,27,514,446,548,357,7
42,913,718,262,565,875,8
53,719,722,876,881,890,0

Таблица А.5. Время увеличения счетчика в разделяемой памяти в Digital Unix 4.0B (в секундах) 

Кол-во потоковВзаимное исключение PosixБлокировка чтения-записиСемафор Posix в памятиИменованный семафор PosixСемафор System VСемафор System V с UNDOБлокировка записей fcntl
12,912,913,214,226,646,696,4
211,440,8742,5771,654,993,9
328,473,21080,51074,584,5141,9
449,395,01534,11502,2109,9188,4
567,3126,31923,31764,1137,3233,6

Результаты синхронизации процессов

 В табл. А.4 и А.5 и на соответствующих рисунках были приведены результаты синхронизации потоков одного процесса. Интересно посмотреть, как взаимодействуют разные процессы. В табл. А.6 и на рис. А.5 приведены результаты измерения времени увеличения счетчика несколькими процессами в Solaris 2.6, а в табл. А.7 и на рис. А.6 — в Digital Unix 4.0B. Результаты похожи на полученные для потоков, однако в Solaris 2.6 теперь получаются одинаковые результаты для первых двух типов семафоров. Мы приводим на графике только первое значение для fcntl, поскольку последующие слишком велики. Как отмечалось в разделе 7.2, Digital Unix 4.0B не поддерживает атрибут PTHREAD_PROCESS_SHARED, поэтому мы не можем измерить скорость работы взаимных исключений в этой системе. Для семафоров Posix в Digital Unix 4.0B опять наблюдаются аномалии. 

Рис. А.5. Время увеличения счетчика в разделяемой памяти (Solaris 2.6)

Рис. А.6. Время увеличения счетчика в разделяемой памяти 


Таблица А.6. Время увеличения счетчика в разделяемой памяти для Solaris 2.6 (в секундах) 

Кол-во процессовВзаимное исключение PosixБлокировка чтения-записиСемафор Posix в памятиИменованный семафор PosixСемафор System VСемафор System V с UNDOБлокировка записей fcntl
10,81,613,614,317,322,190,7
21,63,929,229,234,941,6244,5
32,36,441,642,954,060,1376,4
43,112,257,358,872,481,9558,0
54,020,470,473,587,8102,6764,0

Таблица А.7. Время увеличения счетчика в разделяемой памяти для Digital Unix 4.0B (в секундах)

Количество процессовСемафор Posix в памятиИменованный семафор PosixСемафор System VСемафор System V с UNDOБлокировка записей fcntl
112,812,530,149,098,1
2664,8659,258,695,7477,1
31236,11269,896,4146,21785,2
41772,91804,1120,3197,02582,8
52179,92196,8147,7250,93419,2

А.З. Измерение полосы пропускания: программы