Скачиваний:
90
Добавлен:
12.05.2015
Размер:
913.92 Кб
Скачать

12.2. Процессы, потоки и общий доступ к информации

В традиционной модели программирования Unix в системе могут одновременно выполняться несколько процессов, каждому из которых выделяется собственное адресное пространство. Это иллюстрирует рис. 12.1.

рис. 12.1

  1. Два процесса в левой части совместно используют информацию, хранящуюся в одном из объектов файловой системы. Для доступа к этим данным каждый процесс должен обратиться к ядру (используя функции read,write,lseekи аналогичные). Некоторая форма синхронизации требуется при изменении файла, для исключения помех при одновременной записи в файл несколькими процессами и для защиты процессов, читающих из файла, от тех, которые пишут в него.

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

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

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

Потоки. Хотя концепция процессов в системах Unix используется уже очень давно, возможность использовать несколько потоков внутри одного процесса появилась относительно недавно. Стандарт потоков Posix.1, называемый Pthreads, был принят в 1995 году. С точки зрения взаимодействия процессов все потоки одного процесса имеют общие глобальные переменные (то есть поточной модели свойственно использование общей памяти). Однако потокам требуется синхронизация доступа к глобальным данным. Вообще, синхронизация, не являясь собственно формой IPC, часто используется совместно с различными формами IPC для управления доступом к данным.

В главе 14описаны механизмы взаимодействия между потоками одного процесса. Мы предполагаем наличие среды, в которой поддерживается многопоточное программирование, и будем использовать выражения вида “если канал пуст, вызывающий поток блокируется до тех пор, пока какой-нибудь другой поток не произведет запись в канал”. Если система не поддерживает потоки, можно в этом предложении заменить “потоки” на “процессы” и получится классическое определение блокировки в Unix, возникающей при считывании из пустого канала командойread. Однако в системе, поддерживающей потоки, блокируется только поток, запросивший данные из пустого канала, а все остальные потоки процесса будут продолжать выполняться. Записать данные в канал сможет другой поток этого же процесса или какой-либо поток другого процесса.

12.3. Живучесть объектов ipc

Можно определить живучесть (persistence) любого объекта IPC как продолжительность его существования. На рис. 12.2изображены три возможные группы, к которым могут быть отнесены объекты по живучести.

рис. 12.2

  1. Объект IPC, живучесть которого определяется процессом (process-persistent), существует до тех пор, пока не будет закрыт последним процессом, в котором он еще открыт. Примером являются именованные и неименованные каналы (pipes, FIFO).

  2. Объект IPC, живучесть которого определяется ядром (kernel-persistent), существует до перезагрузки ядра или до явного удаления объекта. Примером являются очереди сообщений стандарта System V, семафоры и разделяемая память.

  3. Объект IPC, живучесть которого определяется файловой системой (filesystem-persistent), существует до тех пор, пока не будет удален явно. Его значение сохраняется даже при перезагрузке ядра.

Следует быть аккуратным при определении живучести объекта IPC, поскольку она не всегда очевидна. Например, данные в канале (pipe) обрабатываются ядром, но живучесть каналов определяется процессами, а не ядром, потому что после того, как последний процесс, которым канал был открыт на чтение, закроет его, ядро сбросит все данные и удалит канал. Аналогично, хотя каналы FIFO и обладают именами в файловой системе, живучесть их также определяется процессами, поскольку все данные в таком канале сбрасываются после того, как последний процесс, в котором он был открыт, закроет его.

В табл. 12.1сведена информация о живучести перечисленных ранее объектов IPC.

Таблица 12.1

Живучесть объектов IPC различных типов

Тип IPC

Живучесть определяет

Программный канал (pipe)

Процесс

Именованный канал (FIFO)

Процесс

Взаимное исключение

Процесс

Условная переменная

Процесс

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

Процесс

Блокировка записи fcntl

Процесс

Очередь сообщений System V

Ядро

Семафор System V

Ядро

Память с общим доступом System V

Ядро

Гнездо TCP (TCP socket)

Процесс

Гнездо UDP (UDP socket)

Процесс

Гнездо домена Unix (Unix domain socket)

Процесс

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

Соседние файлы в папке Chapter.4