Ipc кто использует ресурс. Современные примеры работы ICP

29.06.2020

IPC – это, понятие, связанное с , но есть смысл разобраться в том, что это такое, более подробно.

Cодержание:

Теоретическая страничка

Каждый хоть немного представляет себе работу обычной операционной системы.

А теперь представьте, что привычная для нас работа нашей ОС превратилась в своего злого двойника, который не просто не похож на свой оригинал, но еще и выполняет все свои обязанности.

Такое развитие событий вполне могло происходить, не будь встроен в нашу систему IPC.

Если хорошо изучить вопрос о зависимости программ друг от друга, то можно понять, что приложений, не зависящих друг от друга, довольно малое количество.

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

Например, когда у человека в работе возникает вопрос, который зависит от его работы, он берет нужную ему информацию с какого-то источника, будь то человек или любой другой источник.

Хоть «ядро» нашего компьютера искать информацию в каком-то определенном источнике, принцип роботы по сути тот же.

Принцип работы

Для правильного функционирования системы приложениям в обязательном порядке нужна беспрерывная коммуникация между , либо они сами обязаны предоставлять нужную информацию по требованию процессов.

Именно из-за такой потребности в постоянном обмене информацией с приложениями, в операционную систему встраивается не малое количество механизмов, которые отвечают за поддерживание постоянного и безошибочного потока информации.

Такие механизмы или программы носят название «межпроцессорное взаимодействие» – с перевода Inter-process Communication (IPC).

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

Работает данная программа непосредственно в самой операционной системе, и является основой для передачи любой информации.

Примеры работы IPC

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

Существует просто огромное количество примеров, когда данная программа была использована в довольно примитивных, на сегодняшнее время, механизмах.

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

Более старые версии современного IPC присутствовали еще в MS-DOS.

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

В то время решение данного вопроса было очень проблематичным.

Дело в том, что такая связь могла проводить обмен данными, если только их платформы или операционные системы относились к одинаковым моделям.

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

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

  • браузер у вас в системе;
  • сервер – в любой другой системе или абсолютно в любом месте.

И вы совершенно не задаетесь вопросом, какая у серверов операционная система.

Затрагивая общий принцип работы таких форм как IPC, и не только таких, как она, используется в основном концепция «клиент-сервер».

Понятно, что «клиент» - это приложение, которое запрашивает информацию, а запрос информации идет уже к «серверу» - приложению которое предоставляет нужную информацию.

Общее положение

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

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

На сегодняшний день требования к операционным системам увеличивается пропорционально с ростом уровня технологий.

Данный рост вызван тем, что каждый день на наши операционные системы выходит все больше и больше каких-то дополнений которые в свою очередь улучшают характеристики нашего компьютера.

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

Данные критерии имеют очень высокую важность в роботе нашего компьютера.

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

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

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

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

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

Три основных вида IPC

  • Локальный

Этот вид IPC полностью привязан к своему компьютеру, работа осуществляется только в пределах одной системы (компьютера).

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

Из-за своей ограниченности, в плане коммуникационного пространства, данные IPC, могут работать лишь в пределах своей .

Но благодаря такому ограничению для них могут использоваться более быстрые и простые интерфейсы.

  • Удаленный

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

  • Высокоуровневый

Последний и, пожалуй, один из самых тяжелых в использовании вид IPC – высокоуровневый.

Данный вид представляет собой пакет программного обеспечения.

Этот пакет данных создает так называемый «промежуточный слой», который предоставляет возможность общения между системной платформой и приложением.

Обеспечение корректной работы обмена данных

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

Вот примеры их области деятельности:

1 К онкурентны е ситуации между процессами. Можем представить себе идеальную систему, в которой проходит лишь одно действие, это считывание данных с одного файла. Данная система находиться в полном спокойствии до тех пор, пока одному из процессов не понадобиться изменить данный файл. В таком случае между процессами возникает «конкурентная ситуация». Это можно сравнить с камешком в каком-то механизме.

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

А что насчет тех процессов, которые требуют неотъемлемой скорости своего решения?

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

Через некоторое время была придуманная идея создания очередей, которые осуществляли такой распорядок процессов, которые не мешали основным или более важным процессам.

Также, существует термин, который и в теории, и на практике обоснован своим названием – это тупик.

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

Если проще объяснить, то на практике получается следующее: у нас есть процесс X, когда он получает доступ к файлу X, он начинает ждать, когда освободиться файл Y, для завершения своей роботы. Но вместе с ними процесс Y, получив доступ к файлу Y, ждет, пока освободится файл X.

Данные процессы замыкаются между собой в данный момент и ждут взаимного освобождения файла, при этом, не освобождая свой файл.

Такого «замыкания» можно избежать, если пользователь позаботиться о том, чтобы ресурсы были пронумерованы.

Также они должны быть построены строго в восходящем порядке номеров.

Современные примеры работы ICP

Чтобы наглядно изобразить взаимодействие программ на одном компьютере, существует знакомый нам ресурс – буфер обмена.

Не удивляйтесь, наш старый добрый буфер обмена также является одной из механизмов IPC.

А принцип его работы заключен в следующем: выделенный вами текст из текстового редактора после выделения помещается в или в ту же программу для верстки.

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

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

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

Стоит заметить, что множество из них были реализованы в Windows 9x, а еще большее количество в Windows NT/2000.

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

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

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

Для тех людей, которые думают, что развития в данной технологии не предвещается, есть один факт, который изменит ваше мнение.

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

Что такое IPC$? Я слышал, что через него возможен удаленный взлом? Нужно ли отключать этот ресурс, если да, то как это сделать?

IPC$, или Inter-Process Communication, представляет собой специальный административный ресурс, предназначенный для создания именованных каналов. Посредством последних компьютеры обмениваются в Сети различной служебной информацией. IPC$ также служит для дистанционного управления сервером (рис. 10.1).

Рис. 10.1. Включение сетевой службы обмена информацией IPC$

Чтобы решить, отключать данный ресурс или нет, необходимо учесть следующее:

¦ если это рабочая станция, которой нужно управлять удаленно, лучше не отключать;

¦ если рабочая станция не требует удаленного администрирования, можно и отключить;

¦ если это сервер, то отключать и вовсе не стоит, так как к нему будет невозможно достучаться по сети.

Отключается IPC$ через CMD командой net share ipc$ /delete (после перезагрузки данный ресурс все равно сам включается, поэтому можно написать соответствующий BAT-файл и поместить его в автозагрузку).

Мой компьютер находится в локальной сети. Необходимо сделать так, чтобы машина предоставляла открытые для общего доступа ресурсы, и вместе с тем так, чтобы скрытые общие ресурсы C$, D$ и др. были недоступны. Как это сделать?

Все, что вам необходимо сделать, – это создать параметр AutoshareWks типа DWORD c нулевым значением в следующем разделе: .


Что такое спуффинг и как от него защититься?

Фактически, спуффинг – это подмена. В данном случае имеется в виду IP-спуф-финг, то есть подмена IP. Подмена, при которой злонамеренный пользователь, воспользовавшись чужим IP-адресом, находящимся в пределах доверенной зоны IP-адресов, или авторизованным внешним адресом, выдает себя за объект, которому можно доверять. Чаще всего для защиты от IP-спуффинга применяют метод привязки IP-адреса к адресу сетевой карты (MAC-адрес), но и этот способ несовершенен: в настоящее время известны утилиты, подменяющие текущий MAC.

Что такое сниффинг и существуют ли от него конкретные меры защиты?

В простейшем случае под сниффингом подразумевается перехват пакетов по Сети. Более конкретно: сниффер переводит сетевую карту (там, где он установлен) в так называемый "неразборчивый режим", благодаря которому машина злоумышленника захватывает все сетевые пакеты, даже те, которые ей не предназначены. Пример сниффера – Cain & Abel. В качестве защиты при построении локальной сети можно порекомендовать использование свитчей (коммутатор), а не хабов (концентратор), а также использование протоколов, не передающих данные в открытом виде (SSH, SSL, Kerberos). Но и в этом случае возможен перехват пакетов с помощью продвинутых техник (например, ARP Poizoning).

Что такое фишинг и можно ли от него защититься?

Фишинг представляет собой технику обмана посетителей сайта. Суть: посетитель заходит на сайт, очень похожий на оригинал, заполняет графы, требующие ввода конфиденциальной информации (номер кредитной карты, пароль и т. д.). Далее вся эта информация отправляется злоумышленнику, создавшему этот лже-сайт. Инструменты защиты от фишинга можно найти в новейших версиях интернет-обозревателей, а также в антивирусных пакетах и межсетевых экранах. Однако же следует признать, что и по сей день эффективного способа защиты от фишинга не существует. Главный инструмент защиты в данном случае – это бдительность пользователя.

Известно, что многие вирусы подменяют системные файлы своими. Как определить эту подмену?

Чтобы всегда быть в курсе подобных "проделок", необходимо включить функцию уведомления о защите файлов. Делается это путем внесения в реестр по адресу HKEY_ LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Sys-temFileProtection параметра типа DWORD ShowPopups равного 1.

Как в IE очистить запомненные пароли?

В Internet Explorer интегрирована достаточно удобная вещь – автозаполнение и запоминание пароля. Чтобы стереть запомненные пароли, достаточно сделать следующее: в IE зайти в Сервис > Свойства обозревателя > Содержание > Личные данные > Автозаполнение, затем нажать кнопку Очистить пароли.

Каким образом я могу скрыть адреса посещенных сайтов, которые автоматически высвечиваются в адресной строке, когда я ввожу новый адрес?

Подобные следы можно ликвидировать, удалив соответствующие записи реестра по адресу . Примечание: здесь же сохраняются и другие следы, такие как история доступа к удаленным дискам C$ , D$ для LAN, история того, что вы набирали в поисковых формах, и т. д.

После проверки «Касперским» выяснилось, что в системе изменена главная загрузочная запись. Что это может быть и как восстановить первоначальное состояние загрузочной записи (рис. 10.2)?




Рис. 10.2. Проверить загрузочные записи?

Скорее всего, измененный загрузчик – последствия boot-вируса, хотя не исключено, что загрузчик изменился и не по причине вирусной инфекции. Восстановить загрузчик можно из консоли восстановления: для этого необходимо загрузиться в Recovery Console и прописать команды fix mbr и fix boot. Загрузиться в Recovery Console можно через загрузочный ХР-диск, выбрав Repair Windows XP instaLLation ® и Recovery ConsoLe ©. Однако восстановление таким образом – не лучший способ. В большинстве случаев загрузчик все же не восстанавливается. Решение подобных проблем под силу лишь специализированному ПО, в качестве яркого примера которого можно привести ADINF32.


Подскажите, где в «Антивирусе Касперского 7.0» прописываются обновления. А то при переустановке системы придется загружать все обновления снова.

Обновления – папка с базами располагается по адресу and Set-tings\All Users\Application Data\Kaspersky Lab\AVP7\Bases.


Учитывая результаты многочисленных тестов, можно сказать, что ни один из ныне существующих браузеров не является безопасным на 100 %. Между тем некоторые из продуктов все же можно считать достаточно безопасными. Одним из таких продуктов является Opera.


Ситуация такая: мой компьютер в локальной сети и выход в Интернет у меня через карточку. Лимит старой карточки исчерпан, но ввести новые логин и пароль возможности нет, так как при попытке входа на какой-либо сайт не появляется окно аутентификации с сервером (все настройки прокси-сервера правильные). Как вернуть окно ввода логина и пароля?

Чтобы вновь появилось окно аутентификации, необходимо удалить старый логин и пароль через оснастку Учетные записи пользователей (рис. 10.3) – для этого зайдите в меню Пуск? Выполнить, введите команду control userpasswords2, в появившемся окне нажмите Дополнительно? Управление паролями? Удалить.


При загрузке системы «Антивирус Касперского», который ранее работал без сбоев, почему-то перестал запускаться; при попытке принудительного запуска он тоже сам отключается. Что это может быть и как с этим бороться?

Скорее всего, ваша система инфицирована вирусом, отключающим "Антивирус Касперского". Подобная "зараза", скорее всего, настроена на отключение и других популярных антивирусных продуктов. Выход – загрузиться с чистой среды, например с загрузочного диска (Windows LiveCD). Далее, как вариант, под этой средой проверить систему антивирусом, не требующим установки (такой антивирус может быть запущен с флэшки, как пример – популярный продукт Dr.Web CureIt Сканер (рис. 10.4), который можно скачать с официального сайта Dr.Web).



Рис. 10.3. Управление паролями




Рис. 10.4. Сканер CureIt в действии


Проверил свой жесткий диск «Касперским» и в дистрибутивах Panda Titanium обнаружил самый настоящий вирус! Как быть?

Скорее всего, файл ничем не инфицирован, и поднимать тревогу не стоит. Большинство антивирусных программ время от времени срабатывают при проверке файлов других антивирусов.


Я начинающий системный администратор и хотел бы узнать ваше мнение о том, какую из серверных операционных систем можно считать наиболее надежной и производительной?


Мой межсетевой экран постоянно сообщает о пришедших откуда-то пакетах с флагом «syn». Что это значит?

Скорее всего, вашу машину кто-то или что-то (сетевой червь, к примеру) сканирует. Сканирование, как правило, является подготовкой к атаке. Поэтому вам есть над чем задуматься.

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

В процессе развития операционных систем семейства Unix за последние 30 лет методы передачи сообщений эволюционировали следующим образом:

■ Каналы (pipes - глава 4) были первой широко используемой формой взаимодействия процессов, доступной программам и пользователю (из интерпретатора команд). Основным недостатком каналов является невозможность их использования между процессами, не имеющими общего родителя (ancestor), но этот недостаток был устранен с появлением именованных каналов (named pipes), или каналов FIFO (глава 4).

■ Очереди сообщений стандарта System V (System V message queues - глава 4) были добавлены к ядрам System V в начале 80-х. Они могут использоваться для передачи сообщений между процессами на одном узле вне зависимости от того, являются ли эти процессы родственными. Несмотря на сохранившийся префикс «System V», большинство современных версий Unix, включая и те, которые не произошли от System V, поддерживают эти очереди.

ПРИМЕЧАНИЕ

В отношении процессов Unix термин «родство» означает, что у процессов имеется общий предок. Подразумевается, что процессы, являющиеся родственниками, были созданы этим процессом-предком с помощью одной или нескольких «вилок» (forks). Простейшим примером будет вызов fork некоторым процессом дважды, что приведет к созданию двух порожденных процессов. Тогда можно говорить о родстве этих процессов между собой. Естественно, каждый порожденный процесс является родственником породившего. Родитель может позаботиться о возможности взаимодействия с порожденным процессом (создав канал или очередь сообщений) перед вызовом fork, и этот объект IPC будет унаследован порожденным процессом. Более подробно о наследовании объектов IPC рассказано в табл. 1.4. Нужно также отметить, что все процессы Unix теоретически являются потомками процесса init, который запускает все необходимое в процессе загрузки системы (bootstrapping). С практической точки зрения отсчет родства процессов лучше вести с оболочки (login shell) и всех процессов, ею созданных. В главе 9 рассказано о сеансах и родственных отношениях процессов более подробно.

ПРИМЕЧАНИЕ

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

■ Очереди сообщений Posix (Posix message queues - глава 5) были добавлены в стандарт Posix (1003.1b-1993, о котором более подробно рассказано в разделе 1.7). Они могут использоваться для взаимодействия родственных и неродственных процессов на каком-либо узле.

■ Удаленный вызов процедур (remote procedure calls - RPC, часть 5) появился в 80-х в качестве средства для вызова функций на одной системе (сервере) программой, выполняемой на другой системе (клиенте). Это средство было разработано в качестве альтернативы для упрощения сетевого программирования. Поскольку между клиентом и сервером обычно передается информация (передаются аргументы для вызова функции и возвращаемые значения) и поскольку удаленный вызов процедур может использоваться между клиентом и сервером на одном узле, RPC можно также считать одной из форм передачи сообщений.

Интересно также взглянуть на эволюцию различных форм синхронизации в процессе развития Unix:

■ Самые первые программы, которым требовалась синхронизация (чаще всего для предотвращения одновременного изменения содержимого файла несколькими процессами), использовали особенности файловой системы, некоторые из которых описаны в разделе 9.8,

■ Возможность блокирования записей (record locking - глава 9) была добавлена к ядрам Unix в начале 80-х и стандартизована в версии Posix.1 в 1988.

■ Семафоры System V (System V semaphores - глава 11) были добавлены вместе с возможностью совместного использования памяти (System V shared memory - глава 14) и одновременно с очередями сообщений System V (начало 80-х). Эти IPC поддерживаются большинством современных версий Unix.

■ Семафоры Posix (Posix semaphores - глава 10) и разделяемая память Posix (Posix shared memory- глава 13) были также добавлены в стандарт Posix (1003.1b-1993, который ранее упоминался в связи с очередями сообщений Posix).

■ Взаимные исключения и условные переменные (mutex, conditional variable - глава 7) представляют собой две формы синхронизации, определенные стандартом программных потоков Posix (Posix threads, Pthreads - 1003.1с-1995). Хотя обычно они используются для синхронизации между потоками, их можно применять и при организации взаимодействия процессов.

■ Блокировки чтения-записи (read-write locks - глава 8) представляют собой дополнительную форму синхронизации. Она еще не включена в стандарт Posix, но, вероятно, скоро будет.

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

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

Рис. 1.1. Совместное использование информации процессами


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

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

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

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

Потоки

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

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

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

1.3. Живучесть объектов IPC

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

Рис. 1.2. Живучесть объектов IPC


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

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

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

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

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


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

Тип IPC Живучесть определяет
Программный канал (pipe) Процесс
Именованный канал (FIFO) Процесс
Взаимное исключение Posix (mutex) Процесс
Условная переменная Posix (condition variable) Процесс
Блокировка чтения-записи Posix (lock) Процесс
Блокировка записи fcntl Процесс
Очередь сообщений Posix (message queue) Ядро
Именованный семафор Posix (named semaphore) Ядро
Семафор Posix в памяти (memory-based semaphore) Процесс
Разделяемая память Posix (shared memory) Ядро
Очередь сообщений System V Ядро
Семафор System V Ядро
Ядро
Сокет TCP (TCP socket) Процесс
Сокет UDP (UDP socket) Процесс
Доменный сокет Unix (Unix domain socket) Процесс

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

1.4. Пространства имен

Если два неродственных процесса используют какой-либо вид IPC для обмена информацией, объект IPC должен иметь имя или идентификатор, чтобы один из процессов (называемый обычно сервером - server) мог создать этот объект, а другой процесс (обычно один или несколько клиентов - client) мог обратиться к этому конкретному объекту.

Программные каналы (pipes) именами не обладают (и поэтому не могут использоваться для взаимодействия между неродственными процессами), но каналам FIFO сопоставляются имена в файловой системе, являющиеся их идентификаторами (поэтому каналы FIFO могут использоваться для взаимодействия неродственных процессов). Для других типов IPC, рассматриваемых в последующих главах, используются дополнительные соглашения об именовании (naming conventions). Множество возможных имен для определенного типа IPC называется его пространством имен (name space). Пространство имен - важный термин, поскольку для всех видов IPC, за исключением простых каналов, именем определяется способ связи клиента и сервера для обмена сообщениями.

В табл. 1.2 сведены соглашения об именовании для различных видов IPC.


Таблица 1.2. Пространства имен для различных типов IPC

Тип IPC Пространство имен для создания или открытия Идентификатор после открытия Posix.1 1996 Unix 98
Канал (Без имени) Дескриптор
FIFO Имя файла (pathname) Дескриптор
Взаимное исключение Posix (Без имени) Указатель типа pthread_mutex_t
Условная переменная Posix (Без имени) Указатель типа pthread_cond_t
(Без имени) Указатель типа pthread_rwlock_t
Блокировка записей fcntl Имя файла Дескриптор
Разделяемая память Posix Posix-имя IPC Дескриптор
Очередь сообщений System V Ключ key_t Идентификатор IPC System V
Семафор System V Ключ key_t Идентификатор IPC System V
Разделяемая память System V Ключ key_t Идентификатор IPC System V
Двери (doors) Имя файла Дескриптор
Удаленный вызов процедур (RPC) Sun Программа/версия Дескриптор (handle) RPC
Сокет TCP IP-адрес и порт TCP Дескриптор .1g
Сокет UDP IP-адрес и порт TCP Дескриптор .1g
Доменный сокет Unix (domain socket) Полное имя файла Дескриптор .1g

Здесь также указано, какие формы IPC содержатся в стандарте Posix.1 1996 года и какие были включены в стандарт Unix 98. Об обоих этих стандартах более подробно рассказано в разделе 1.7. Для сравнения мы включили в эту таблицу три типа сокетов, которые подробно описаны в . Обратите внимание, что интерфейс сокетов (Application Program Interface - API) стандартизируется рабочей группой Posix.1g и должен в будущем стать частью стандарта Posix.1.

Хотя стандарт Posix. 1 и дает возможность использования семафоров, их поддержка не является обязательной для производителей. В табл. 1.3 сведены функции, описанные в стандартах Posix.1 и Unix 98. Каждая функция может быть обязательной (mandatory), неопределенной (not defined) или необязательной (дополнительной - optional). Для необязательных функций мы указываем имя константы (например, _POSIX_THREADS), которая будет определена (обычно в заголовочном файле ), если эта функция поддерживается. Обратите внимание, что Unix 98 содержит в себе Posix.1 в качестве подмножества.


Таблица 1.3. Доступность различных форм IPC

Тип IPC Posix.1 1996 Unix 98
Программный канал Обязателен Обязателен
FIFO Обязателен Обязателен
Взаимное исключение Posix _POSIX_THREADS Обязателен
Условная переменная Posix _POSIX_THREADS Обязателен
Взаимные исключения и условные переменные между процессами _POSIX_THREADS_PROCESS_SHARED Обязателен
Блокировка чтения-записи Posix (He определен) Обязателен
Блокировка записей fcntl Обязателен Обязателен
Очередь сообщений Posix _POSIX_MESSAGE_PASSING _XOPEN_REALTIME
Семафоры Posix _POSIX_SEMAPHORES_ _XOPEN_REALTIME
Память с общим доступом Posix _POSIX_SHARED_MEMORY_OBJECTS _XOPEN_REALTIME
Очередь сообщений System V (He определен) Обязателен
Семафор System V (He определен) Обязателен
Память с общим доступом System V (He определен) Обязателен
Двери (doors) (He определен) (Не определен)
Удаленный вызов процедур Sun (He определен) (Не определен)
Отображение памяти mmap _POSIX_MAPPED_FILES или POSIX_SHARED_MEMORY_OBJECTS Обязателен
Сигналы реального времени (realtime signals) _POSIX_REALTIME_SIGNALS _XOPEN_REALTIME

1.5. Действие команд fork, exec и exit на объекты IPC

Нам нужно достичь понимания действия функций fork, exec и _exit на различные формы IPC, которые мы обсуждаем (последняя из перечисленных функций вызывается функцией exit). Информация по этому вопросу сведена в табл. 1.4.

Большинство функций описаны далее в тексте книги, но здесь нужно сделать несколько замечаний. Во-первых, вызов fork из многопоточного процесса (multithreaded process) приводит к беспорядку в безымянных переменных синхронизации (взаимных исключениях, условных переменных, блокировках и семафорах, хранящихся в памяти). Раздел 6.1 книги содержит необходимые детали. Мы просто отметим в добавление к таблице, что если эти переменные хранятся в памяти с общим доступом и создаются с атрибутом общего доступа для процессов, они будут доступны любому процессу, который может обращаться к этой области памяти. Во-вторых, три формы IPC System V не могут быть открыты или закрыты. Из листинга 6.6 и упражнений 11.1 и 14.1 видно, что все, что нужно знать, чтобы получить доступ к этим трем формам IPC, - это идентификатор. Поэтому они доступны всем процессам, которым известен этот идентификатор, хотя для семафоров и памяти с общим доступом требуется некая особая обработка.


Таблица 1.4. Действие fork, exec и _exit на IPC

Тип IPC fork exec _exit
Неименованные и именованные каналы Порожденный процесс получает копии всех дескрипторов родительского процесса Все открытые дескрипторы остаются открытыми, если для них не установлен бит FD_CLOEXEC Все открытые дескрипторы закрываются, данные из программного канала и FIFO удаляются после последнего закрытия
Очереди сообщений Posix Порожденный процесс получает копии всех открытых родительских процессов Все открытые дескрипторы очередей сообщений закрываются
Очереди сообщений System V Не действует Не действует Не действует
Взаимные исключения и условные переменные Posix Общий доступ, если используется разделяемая память с атрибутом разделения между процессами Исчезает, если не находится в разделяемой памяти, которая остается открытой и имеет атрибут разделения
Блокировки чтения-записи Posix Исчезает, если не хранится в разделяемой памяти, которая остается открытой и имеет атрибут разделения Исчезает, если не хранится в разделяемой памяти, которая остается открытой и имеет атрибут разделения
Семафоры Posix, хранящиеся в памяти Общий доступ, если используется память с общим доступом и атрибутом разделения между процессами Исчезает, если не хранится в разделяемой памяти, которая остается открытой и имеет атрибут разделения Исчезает, если не хранится в разделяемой памяти, которая остается открытой и имеет атрибут разделения
Именованные семафоры Posix Все открытые в родительском процессе остаются открытыми в порожденном Все открытые закрываются Все открытые закрываются
Семафоры System V Все значения semadj в порожденном процессе устанавливаются в 0 Все значения semadj передаются новой программе Все значения semadj добавляются к значению соответствующего семафора
Блокировка записей fcntl Блокировки в родительском процессе не наследуются порожденным процессом Блокировки не изменяются до тех пор, пока не закроется дескриптор Все несброшенные блокировки, установленные процессом, снимаются
Отображение памяти Отображения памяти сбрасываются (unmap)
Разделяемая память Posix Отображения памяти родительского процесса сохраняются в порожденном Отображения памяти сбрасываются Отображения памяти сбрасываются
Разделяемая память System V Присоединенные сегменты разделяемой памяти остаются присоединенными в порожденном процессе Присоединенные сегменты разделяемой памяти отсоединяются
Двери (doors) Порожденный процесс получает копии всех открытых дескрипторов родительского процесса, но только родительский процесс является сервером при активизации дверей через дескрипторы Все дескрипторы дверей должны быть закрыты, потому что они создаются с установленным битом FD_CLOEXEC Все открытые дескрипторы закрываются

1.6. Обработка ошибок: функции-обертки

В любой реальной программе при любом вызове требуется проверка возвращаемого значения на наличие ошибки. Поскольку обычно работа программ при возникновении ошибок завершается, мы можем сократить объем текста, определив функции-обертки (wrapper functions), которые осуществляют собственно вызов функции, проверяют возвращаемое значение и завершают работу при возникновении ошибок. В соответствии с соглашениями имена функций-оберток совпадают с именами самих функций, за исключением первой буквы, которая делается заглавной, например

Пример функции-обертки приведен в листинге 1.1

Листинг 1.1. Функция-обертка к функции sem_post
390 if (sem_post(sem) == –1)
391 err_sys("sem_post error");

Если в тексте вы встретите имя функции, начинающееся с заглавной буквы, знайте: это наша собственная функция-обертка. Она вызывает функцию с тем же именем, начинающимся со строчной буквы. Функция-обертка приводит к завершению работы процесса с выводом сообщения об ошибке, если таковая возникает.

При описании исходного кода, включенного в книгу, мы всегда говорим о вызываемой функции самого низкого уровня (например, sem_post), а не о функции-обертке (например, Sem_post). Аналогично в алфавитном указателе приведены имена самих функций, а не оберток к ним.

ПРИМЕЧАНИЕ

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

В начале кода указывается имя исходного файла. В данном примере - это файл wrapunix.c в каталоге lib. Поскольку исходный код всех примеров этой книги распространяется свободно (см. предисловие), вы можете легко найти требуемый файл. Компиляция, выполнение и особенно изменение этих программ в процессе чтения книги - лучший способ изучить концепции взаимодействия процессов.

Хотя может показаться, что использовать такие функции-обертки не слишком выгодно, вы избавитесь от этого заблуждения в главе 7, где мы обнаружим, что функции для работы с потоками (thread functions) не присваивают значение стандартной переменной Unix errno при возникновении ошибки; вместо этого код ошибки просто возвращается функцией. Это означает, что при вызове функции pthread мы должны каждый раз выделять память под переменную, сохранять в ней возвращаемое функцией значение, а затем устанавливать значение переменной errno равным этой переменной, прежде чем вызывать функцию err_sys (листинг В.4). Чтобы не загромождать текст фигурными скобками, мы используем оператор языка Си «запятая» (comma) и совмещаем присваивание значения переменной errno и вызов err_sys в одном операторе, как в нижеследующем примере:

if ((n = pthread_mutex_lock(&ndone_mutex))!=0) errno=n, err_sys("pthread_mutex_lock error");

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

Pthread_mutex_lock(&ndone_mutex);

где используется наша собственная функция-обертка, приведенная в листинге 1.2.

Листинг 1.2. Реализация обертки к функции pthread_mutex_lock
126 Pthread_mutex_lock(pthread_mutex_t *mptr)
129 if ((n=pthread_mutex_lock(mptr))==0)
132 err_sys("pthread_mutex_lock error");

ПРИМЕЧАНИЕ

Аккуратно используя возможности языка Си, мы могли бы применять макросы вместо функций, что увеличило бы скорость выполнения программ, но эти функции-обертки редко бывают (если вообще бывают) узким местом.

Наше соглашение о замене первой буквы имени функции на заглавную является компромиссом. Рассматривалось много других форм записи: использование префикса е (), суффикса _е и т. д. Наш вариант кажется наименее отвлекающим внимание и одновременно дающим визуальное указание на то, что вызывается какая-то другая функция.

Этот метод имеет побочное полезное свойство: проверяются ошибки, возвращаемые функциями, код возврата которых обычно игнорируется, например close и pthread_ mutex_lock.

Далее в тексте книги мы будем использовать эти функции-обертки, если только не потребуется явно проверить наличие ошибки и обработать ее произвольным образом, отличным от завершения процесса. Мы не приводим в книге исходный код для всех оберток, но он свободно доступен в Интернете (см. предисловие).

Значение errno

При возникновении ошибки в функции Unix глобальной переменной errno присваивается положительное значение, указывающее на тип ошибки; при этом функция обычно возвращает значение –1. Наша функция err_sys выводит соответствующее коду ошибки сообщение (например, Resource temporarily unavailable - ресурс временно недоступен, - если переменная errno имеет значение EAGAIN).

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

При работе с несколькими потоками в каждом из них должна быть собственная переменная errno. Выделение переменной каждому потоку происходит автоматически, однако обычно это требует указания компилятору на то, что должна быть возможность повторного входа в программу. Задается это с помощью ключей –D_REENTRANT или –D_POSIX_C_SOURCE=199506L или аналогичных. Часто в заголовке переменная errno определяется как макрос, раскрываемый в вызов функции, если определена константа _REENTRANT. Функция обеспечивает доступ к копии errno, относящейся к данному потоку.

Далее в тексте мы используем выражения наподобие «функция mq_send возвращает EMSGSIZE», означающие, что функция возвращает ошибку (обычно возвращаемое значение при этом равно –1) и присваивает переменной errno значение указанной константы.

1.7. Стандарты Unix

В настоящее время стандарты Unix определяются Posix и The Open Group.

Posix

Название Posix образовано от «Portable Operating System Interface», что означает приблизительно «интерфейс переносимых операционных систем». Это не один стандарт, а целое семейство, разработанное Институтом инженеров по электротехнике и радиоэлектронике (Institute for Electrical and Electronics Engineers - IEEE). Стандарты Posix были также приняты в качестве международных стандартов ISO (International Organization for Standardization, Международная организация по стандартизации) и IEC (International Electrotechnical Commission, Международная электротехническая комиссия), или ISO/IEC. Стандарты Posix прошли несколько стадий разработки.

■ Стандарт IEEE 1003.1-1988 (317 страниц) был первым стандартом Posix. Он определял интерфейс взаимодействия языка С с ядром Unix-типа в следующих областях: примитивы для реализации процессов (вызовы fork, exec, сигналы и таймеры), среда процесса (идентификаторы пользователей, группы процессов), файлы и каталоги (все функции ввода-вывода), работа с терминалом, базы данных системы (файлы паролей и групп), форматы архивов tar и cpio.

ПРИМЕЧАНИЕ

Первый стандарт Posix вышел в рабочем варианте под названием IEEEIX в 1986 году. Название Posix было предложено Ричардом Штолманом (Richard Stallman).

■ Затем вышел стандарт IEЕЕ 1003.1-1990 (356 страниц). Он одновременно являлся и международным стандартом ISO/IEC 9945-1:1990. По сравнению с версией 1988 года изменения в версии 1990 года были минимальными. К заголовку было добавлено: «Part 1: System Application Program Interface (API) » («Часть 1: Системный интерфейс разработки программ (API) [Язык С])», и это означало, что стандарт описывал программный интерфейс (API) языка С.

■ IEEE 1003.2-1992 вышел в двух томах общим объемом около 1300 страниц, и его заголовок содержал строку «Part 2: Shell and Utilities» (Часть 2: «Интерпретатор и утилиты»). Эта часть определяла интерпретатор (основанный на Bourne shell в Unix System V) и около ста утилит (программ, обычно вызываемых из интерпретатора - от awk и basename до vi и уасс). В настоящей книге мы будем ссылаться на этот стандарт под именем Posix. 2.

■ IEEE 1003.1b-1993 (590 страниц) изначально был известен как IEEE P1003.4. Этот стандарт представлял собой дополнение к стандарту 1003.1-1990 и включал расширения реального времени, разработанные рабочей группой Р1003.4: синхронизацию файлов, асинхронный ввод-вывод, семафоры, управление памятью, планирование выполнения (scheduling), часы, таймеры и очереди сообщений.

■ IEEE 1003.1, издание 1996 года (743 страницы), включает 1003.1-1990 (базовый интерфейс API), 1003.1b-1993 (расширения реального времени), 1003.1-1995 (Pthreads - программные потоки Posix) и 1003.1i-1995 (технические поправки к 1003.1b). Этот стандарт также называется ISO/IEC 9945-1: 1996. В него были добавлены три главы о потоках и дополнительные разделы, касающиеся синхронизации потоков (взаимные исключения и условные переменные), планирование выполнения потоков, планирование синхронизации. В настоящей книге мы называем этот стандарт Posix.1.

ПРИМЕЧАНИЕ

Более четверти из 743 страниц стандарта представляли собой приложение, озаглавленное «Rationale and Notes» («Обоснование и примечания»). Это обоснование содержит историческую информацию и объяснение причин, по которым некоторые функции были или не были включены в стандарт. Часто обоснование оказывается не менее полезным, чем собственно стандарт.

К сожалению, стандарты IEEE не являются свободно доступными через Интернет. Информация о том, где можно заказать книгу, дана в библиографии под ссылкой . Обратите внимание, что семафоры были определены в стандарте расширений реального времени, отдельно от взаимных исключений и условных переменных (которые были определены в стандарте Pthreads), что объясняет некоторые различия в интерфейсах API этих средств.

Наконец, заметим, что блокировки чтения-записи не являются частью стандартов Posix. Об этом более подробно рассказано в главе 8.

В будущем планируется выход новой версии IEEE 1003.1, включающей стандарт P1003.1g, сетевые интерфейсы (сокеты и XTI), которые описаны в первом томе этой книги.

В предисловии стандарта Posix.1 1996 года утверждается, что стандарт ISO/IEC 9945 состоит из следующих частей:

1. Системный интерфейс разработки программ (API) (язык С).

2. Интерпретатор и утилиты.

3. Администрирование системы (в разработке).

Части 1 и 2 представляют собой то, что мы называем Posix.1 и Posix.2.

Работа над стандартами Posix постоянно продолжается, и авторам книг, с ними связанных, приходится заниматься стрельбой по движущейся мишени. О текущем состоянии стандартов можно узнать на сайте http://www.pasc.org/standing/sd11.html.

The Open Group

The Open Group (Открытая группа) была сформирована в 1996 году объединением X/Open Company (основана в 1984 году) и Open Software Foundation (OSF, основан в 1988 году). Эта группа представляет собой международный консорциум производителей и потребителей из промышленности, правительства и образовательных учреждений. Их стандарты тоже выходили в нескольких версиях:

■ В 1992 году был опубликован четвертый выпуск (Issue 4), а в 1994 году - вторая его версия (Issue 4, Version 2). Последняя известна также под названием Spec 1170, где магическое число 1170 представляет собой сумму количества интерфейсов системы (926), заголовков (70) и команд (174). Есть и еще два названия: X/Open Single Unix Specification (Единая спецификация Unix) и Unix 95.

■ В марте 1997 года было объявлено о выходе второй версии Единой спецификации Unix. Этот стандарт программного обеспечения называется также Unix 98, и именно так мы ссылаемся на эту спецификацию далее в тексте книги. Количество интерфейсов в Unix 98 возросло с 1170 до 1434, хотя для рабочей станции это количество достигает 3030, поскольку в это число включается CDE (Common Desktop Environment - общее окружение рабочего стола), которое, в свою очередь, требует системы X Window System и пользовательского интерфейса Motif. Подробно об этом написано в книге . Полезную информацию можно также найти по адресу http://www.UNIX-systems.org/version2.

ПРИМЕЧАНИЕ

С этого сайта можно свободно скачать единую спецификацию Unix практически целиком.

Версии Unix и переносимость

Практически все версии Unix, с которыми можно столкнуться сегодня, соответствуют какому-либо варианту стандарта Posix.1 или Posix.2. Мы говорим «какому-либо», потому что после внесения изменений в Posix (например, Добавление расширений реального времени в 1993 и потоков в 1996) производителям обычно требуется год или два, чтобы подогнать свои программы под эти стандарты.

Исторически большинство систем Unix являются потомками либо BSD, либо System V, но различия между ними постепенно стираются, по мере того как производители переходят к использованию стандартов Posix. Основные различия лежат в области системного администрирования, поскольку ни один стандарт Posix на данный момент не описывает эту область.

В большинстве примеров этой книги мы использовали операционные системы Solaris 2.6 и Digital Unix 4.0B. Дело в том, что на момент написания книги (конец 1997 - начало 1998 года) только эти две операционные системы поддерживали System V IPC, Posix IPC и программные потоки Posix (Pthreads).

1.8. Комментарий к примерам IPC

Чаще всего для иллюстрации различных функций в книге используются три шаблона (модели) взаимодействия:

1. Сервер файлов: приложение клиент-сервер, причем клиент посылает серверу запрос с именем файла, а сервер возвращает клиенту его содержимое.

2. Производитель-потребитель: один или несколько потоков или процессов (производителей) помещают данные в буфер общего пользования, а другие потоки или процессы (потребители) производят с этими данными различные операции.

3. Увеличение последовательного номера: один или несколько потоков или процессов увеличивают общий для всех индекс. Число это может храниться в файле с общим доступом или в совместно используемой области памяти.

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

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

1.9. Резюме

Взаимодействие процессов традиционно является одной из проблемных областей в Unix. По мере развития системы предлагались различные решения, и ни одно из них не было совершенным. Мы подразделяем IPC на четыре главных типа.

1. Передача сообщений (каналы, FIFO, очереди сообщений).

2. Синхронизация (взаимные исключения, условные переменные, блокировки чтения-записи, семафоры).

3. Разделяемая память (неименованная и именованная).

4. Вызов процедур (двери в Solaris, RPC Sun).

Мы рассматриваем взаимодействие как отдельных потоков одного процесса, так и нескольких независимых процессов.

Живучесть каждого типа IPC определяется либо процессом, либо ядром, либо файловой системой в зависимости от продолжительности его существования. При выборе типа IPC для конкретного применения нужно учитывать его живучесть.

Другим свойством каждого типа IPC является пространство имен, определяющее идентификацию объектов IPC процессами и потоками, использующими его. Некоторые объекты не имеют имен (каналы, взаимные исключения, условные переменные, блокировки чтения-записи), другие обладают именами в рамках файловой системы (каналы FIFO), третьи характеризуются тем, что в главе 2 названо «именами IPC стандарта Posix», а четвертые - еще одним типом имен, который описан в главе 3 (ключи или идентификаторы IPC стандарта System V). Обычно сервер создает объект IPC с некоторым именем, а клиенты используют это имя для получения доступа к объекту.

В исходных кодах, приведенных в книге, используются функции-обертки, описанные в разделе 1.6, позволяющие уменьшить объем кода, обеспечивая, тем не менее, проверку возврата ошибки для любой вызываемой функции. Имена всех функций-оберток начинаются с заглавной буквы.

Стандарты IEEE Posix - Posix.1, определяющий основы интерфейса С в Unix, и Posix.2, определяющий основные команды, - это те стандарты, к которым движутся большинство производителей. Однако стандарты Posix в настоящее время быстро поглощаются (включаются в качестве части) и расширяются коммерческими стандартами, в частности The Open Group (Unix 98).


Таблица 1.5. Версии модели клиент-сервер

Листинг Описание
4.1 Два канала между родительским и порожденным процессами
4.5 Использует popen и cat
4.6 Использует два канала FIFO между родительским и порожденным процессами
4.7 Два канала FIFO между независимым сервером и неродственным клиентом
4.10 Каналы FIFO между независимым последовательным сервером и несколькими клиентами
4.12 Программный канал или FIFO: формирование записей в потоке байтов
6.7 Две очереди сообщений System V
6.12 Одна очередь сообщений System V с несколькими клиентами
6.16 Одна очередь сообщений System V для каждого клиента; клиентов несколько
15.15 Передача дескриптора через дверь

Таблица 1.6. Версии модели производитель-потребитель

Листинг Описание
7.1 Взаимное исключение, несколько производителей, один потребитель
7.5 Взаимное исключение и условная переменная, несколько производителей, один потребитель
10.8 Именованные семафоры Posix, один производитель, один потребитель
10.11 Семафоры Posix в памяти, один производитель, один потребитель
10.12 Семафоры Posix в памяти, несколько производителей, один потребитель
10.15 Семафоры Posix в памяти, несколько производителей, несколько потребителей
10.18 Семафоры Posix в памяти, один производитель, один потребитель: несколько буферов

Таблица 1.7. Версии программы с увеличением последовательного номера

Листинг Описание
9.1 Индекс в файле, без блокировки
9.3 Индекс в файле, блокировка с помощью fcntl
9.9 Индекс в файле, блокировка с использованием функции open
10.10 Индекс в файле, блокировка с помощью именованного семафора Posix
12.2 Индекс в общей памяти mmap, блокировка с помощью именованного семафора Posix
12.3 Индекс в общей памяти mmap, блокировка с помощью семафора Posix в памяти
12.4 Индекс в неименованной общей памяти 4.4BSD, блокировка с помощью именованного семафора Posix
12.5 Индекс в общей памяти SVR4 /dev/zero, блокировка с помощью именованного семафора Posix
13.6 Индекс в общей памяти Posix, блокировка с помощью семафора Posix в памяти
А.19 Измерение производительности: блокировка взаимным исключением между потоками
А.22 Измерение производительности: блокировка чтения-записи между потоками
А.23 Измерение производительности: блокировка между потоками с помощью семафоров Posix в памяти
А.25 Измерение производительности: блокировка между потоками с помощью именованных семафоров Posix
А.28 Измерение производительности: блокировка между потоками с помощью семафоров System V
А.29 Измерение производительности: блокировка между потоками с помощью fcntl
А.33 Измерение производительности: блокировка между процессами с помощью взаимных исключений

Упражнения

1. На рис 1.1 изображены два процесса, обращающиеся к одному файлу. Если оба процесса только дописывают данные к концу файла (возможно, длинного), какой нужен будет тип синхронизации?

2. Изучите заголовочный файл в вашей системе и выясните, как определена errno.

3. Дополните табл. 1.3 используемыми вами функциями, поддерживаемыми Unix-системами.

ГЛАВА 2

2.1. Введение

Из имеющихся типов IPC следующие три могут быть отнесены к Posix IPC, то есть к методам взаимодействия процессов, соответствующим стандарту Posix:

■ очереди сообщений Posix (глава 5);

■ семафоры Posix (глава 10);

■ разделяемая память Posix (глава 13).

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

Полный список функций, используемых для работы с данными типами IPC, приведен в табл. 2.1.


Таблица 2.1. Функции Posix IPC

Очереди сообщений Семафоры Общая память
Заголовочный файл
Функции для создания, открытия и удаления mq_open mq_close mq_unlink sem_open sem_close sem_unlink sem_init sem_destroy shm_open shm_unlink
Операции управления mq_getattr mq_setattr ftruncate fstat
Операции IPC mq_send mq_receive mq_notify sem_wait sem_trywait sem_post sem_getvalue mmap munmap

2.2. Имена IPC

В табл. 1.2 мы отметили, что три типа IPC стандарта Posix имеют идентификаторы (имена), соответствующие этому стандарту. Имя IPC передается в качестве первого аргумента одной из трех функций: mq_open, sem_open и shm_open, причем оно не обязательно должно соответствовать реальному файлу в файловой системе. Стандарт Posix.1 накладывает на имена IPC следующие ограничения:

■ Имя должно соответствовать существующим требованиям к именам файлов (не превышать в длину РАТНМАХ байтов, включая завершающий символ с кодом 0).

■ Если имя начинается со слэша (/), вызов любой из этих функций приведет к обращению к одной и той же очереди. В противном случае результат зависит от реализации.

■ Интерпретация дополнительных слэшей в имени зависит от реализации.

Таким образом, для лучшей переносимости имена должны начинаться со слэша (/) и не содержать в себе дополнительных слэшей. К сожалению, эти правила, в свою очередь, приводят к проблемам с переносимостью.

В системе Solaris 2.6 требуется наличие начального слэша и запрещается использование дополнительных. Для очереди сообщений, например, при этом создаются три файла в каталоге /tmp, причем имена этих файлов начинаются с.MQ. Например, если аргумент функции mq_open имеет вид /queue.1234, то созданные файлы будут иметь имена /tmp/.MQDqueue.1234, /tmp/.MQLqueue.1234 и /tmp/.MQPqueue.1234. В то же время в системе Digital Unix 4.0B просто создается файл с указанным при вызове функции именем.

Проблема с переносимостью возникает при указании имени с единственным слэшем в начале: при этом нам нужно иметь разрешение на запись в корневой каталог. Например, очередь с именем /tmp.1234 допустима стандартом Posix и не вызовет проблем в системе Solaris, но в Digital Unix возникнет ошибка создания файла, если разрешения на запись в корневой каталогу программы нет. Если мы укажем имя /tmp/test.1234, проблемы в Digital Unix и аналогичных системах, создающих файл с указанным именем, пропадут (предполагается существование каталога /tmp и наличие у программы разрешения на запись в него, что обычно для большинства систем Unix), однако в Solaris использование этого имени будет невозможно.

Для решения подобных проблем с переносимостью следует определять имя в заголовке с помощью директивы #define, чтобы обеспечить легкость его изменения при переносе программы в другую систему.

ПРИМЕЧАНИЕ

Разработчики стремились разрешить использование очередей сообщений, семафоров и разделяемой памяти для существующих ядер Unix и в независимых бездисковых системах. Это тот случай, когда стандарт получается чересчур общим и в результате вызывает проблемы с переносимостью. В отношении Posix это называется «как стандарт становится нестандартным».

Стандарт Posix.1 определяет три макроса:

которые принимают единственный аргумент - указатель на структуру типа stat, содержимое которой задается функциями fstat, lstat и stat. Эти три макроса возвращают ненулевое значение, если указанный объект IPC (очередь сообщений, семафор или сегмент разделяемой памяти) реализован как особый вид файла и структура stat ссылается на этот тип. В противном случае макрос возвращает 0.

ПРИМЕЧАНИЕ

К сожалению, проку от этих макросов мало, потому что нет никаких гарантий, что эти типы IPC реализованы как отдельные виды файлов. Например, в Solaris 2.6 все три макроса всегда возвращают 0.

Все прочие макросы, используемые для проверки типа файла, имеют имена, начинающиеся с S_IS, и принимают всегда единственный аргумент: поле st_mode структуры stat. Поскольку макросы, используемые для проверки типа IPC, принимают аргументы другого типа, их имена начинаются с S_TYPEIS.

Функция px_ipc_name

Существует и другое решение упомянутой проблемы с переносимостью. Можно определить нашу собственную функцию px_ipc_name, которая добавляет требуемый каталог в качестве префикса к имени Posix IPC.

char *px_ipc_name(const char *name );
/* Возвращает указатель при успешном завершении, NULL при возникновении ошибки */

ПРИМЕЧАНИЕ

Так выглядят листинги наших собственных функций, то есть функций, не являющихся стандартными системными. Обычно включается заголовочный файл unpipc.h (листинг B.1).

Аргумент пате (имя) не должен содержать слэшей. Тогда, например, при вызове px_ipc_name("test1") будет возвращен указатель на строку /test1 в Solaris 2.6 или на строку /tmp/test1 в Digital Unix 4.0B. Память для возвращаемой строки выделяется динамически и освобождается вызовом free. Можно установить произвольное значение переменной окружения PX_IPC_NAME, чтобы задать другой каталог по умолчанию.

В листинге 2.1 приведен наш вариант реализации этой функции.

ПРИМЕЧАНИЕ

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

Функция snprintf еще не является частью стандарта ANSI С, но планируется ее включение в обновленный стандарт, называющийся С9Х. Тем не менее многие производители включают ее в стандартную библиотеку С. Везде в тексте мы используем функцию snprintf в нашем собственном варианте, обеспечивающем вызов sprintf, если в системной библиотеке функция snprinft отсутствует.

Листинг 2.1. Функция px_ipc_name в нашей реализации.
3 px_ipc_name(const char *name)
6 if ((dst = malloc(РАТН_МАХ)) == NULL)
8 /* есть возможность задать другое имя каталога с помощью переменной окружения */
9 if ((dir = getenv("PX IPC_NAME")) == NULL) {
11 dir = POSIX_IPC_PREFIX; /* из "config.h" */
13 dir = "/tmp/"; /* по умолчанию */
16 /* имя каталога должно заканчиваться символом "/" */
17 slash = (dir == "/") ? "" : "/";
18 snprintf(dst, PATH_MAX, "%s%s%s", dir, slash, name);
19 return(dst); /* для освобождения этого указателя можно вызвать free() */

2.3. Создание и открытие каналов IPC

Все три функции, используемые для создания или открытия объектов IPC: mq_open, sem_open и shm_open, - принимают специальный флаг oflag в качестве второго аргумента. Он определяет параметры открытия запрашиваемого объекта аналогично второму аргументу стандартной функции open. Все константы, из которых можно формировать этот аргумент, приведены в табл. 2.2.


Таблица 2.2. Константы, используемые при создании и открытии объектов IPC

Описание mq_open sem_open shm_open
Только чтение О_RDONLY О_RDONLY
Только запись О_WRONLY
Чтение и запись О_RDWR О_RDWR
Создать, если не существует О_CREAT О_CREAT О_CREAT
Исключающее создание О_EXCL О_EXCL О_EXCL
Без блокировки О_NONBLOCK
Сократить (truncate) существующий O_TRUNC

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

Указание прочих флагов из табл. 2.2 не является обязательным.

O_CREAT - создание очереди сообщений, семафора или сегмента разделяемой памяти, если таковой еще не существует (см. также флаг O_EXCL, влияющий на результат).

При создании новой очереди сообщений, семафора или сегмента разделяемой памяти требуется указание по крайней мере одного дополнительного аргумента, определяющего режим. Этот аргумент указывает биты разрешения на доступ к файлу и формируется путем побитового логического сложения констант из табл. 2.3.


Таблица 2.3. Константы режима доступа при создании нового объекта IPC

Эти константы определены в заголовке . Указанные биты разрешений изменяются наложением маски режима создания файлов для данного процесса (с. 83-85 ) или с помощью команды интерпретатора umask.

Как и со вновь созданным файлом, при создании очереди сообщений, семафора или сегмента разделяемой памяти им присваивается идентификатор пользователя, соответствующий действующему (effective) идентификатору пользователя процесса. Идентификатор группы семафора или сегмента разделяемой памяти устанавливается равным действующему групповому идентификатору процесса или групповому идентификатору, установленному по умолчанию для системы в целом. Групповой идентификатор очереди сообщений всегда устанавливается равным действующему групповому идентификатору процесса (на с. 77-78 рассказывается о групповых и пользовательских идентификаторах более подробно).

ПРИМЕЧАНИЕ

Кажется странным наличие разницы в установке группового идентификатора для разных видов Posix IPC. Групповой идентификатор нового файла, создаваемого с помощью функции open, устанавливается равным либо действительному идентификатору группы процесса, либо идентификатору группы каталога, в котором создается файл, но функции IPC не могут заранее предполагать, что для объекта IPC создается реальный файл в файловой системе.

O_EXCL - если этот флаг указан одновременно с O_CREAT, функция создает новую очередь сообщений, семафор или объект разделяемой памяти только в том случае, если таковой не существует. Если объект уже существует и указаны флаги O_CREAT | O_EXCL, возвращается ошибка EEXIST.

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

O_NONBLOCK - этот флаг создает очередь сообщений без блокировки. Блокировка обычно устанавливается для считывания из пустой очереди или записи в полную очередь. Об этом более подробно рассказано в подразделах, посвященных функциям mq_send и mq_receive раздела 5.4.

O_TRUNC - если уже существующий сегмент общей памяти открыт на чтение и запись, этот флаг указывает на необходимость сократить его размер до 0.

На рис. 2.1 показана реальная последовательность логических операций при открытии объекта IPC. Что именно подразумевается под проверкой разрешений доступа, вы узнаете в разделе 2.4. Другой подход к изображенному на рис. 2.1 представлен в табл. 2.4.

Рис. 2.1. Логика открытия объекта IPC


Обратите внимание, что в средней строке табл. 2.4, где задан только флаг O_CREAT, мы не получаем никакой информации о том, был ли создан новый объект или открыт существующий.


Таблица 2.4. Логика открытия объекта IPC

Аргумент oflag Объект не существует Объект уже существует
Нет специальных флагов Ошибка, errno=ENOENT
O_CREAT OK, создается новый объект OK, открывается существующий объект
O_CREAT|O_EXCL OK, создается новый объект Ошибка, errno=EEXIST

2.4. Разрешения IPC

Новая очередь сообщений, именованный семафор или сегмент разделяемой памяти создается функциями mq_open, sem_open и shm_open, при условии, что аргумент oflag содержит константу O_CREAT. Согласно табл. 2.3, любому из данных типов IPC присваиваются определенные права доступа (permissions), аналогичные разрешениям доступа к файлам в Unix.

При открытии существующей очереди сообщений, семафора или сегмента разделяемой памяти теми же функциями (в случае, когда не указан флаг O_CREAT или указан O_CREAT без O_EXCL и объект уже существует) производится проверка разрешений:

1. Проверяются биты разрешений, присвоенные объекту IPC при создании.

2. Проверяется запрошенный тип доступа (O_RDONLY, O_WRONLY, O_RDWR).

3. Проверяется действующий идентификатор пользователя вызывающего процесса, действующий групповой идентификатор процесса и дополнительные групповые идентификаторы процесса (последние могут не поддерживаться).

Большинством систем Unix производятся следующие конкретные проверки:

1. Если действующий идентификатор пользователя для процесса есть 0 (привилегированный пользователь), доступ будет разрешен.

2. Если действующий идентификатор пользователя процесса совпадает с идентификатором владельца объекта IPC: если соответствующий бит разрешения для пользователя установлен, доступ разрешен, иначе в доступе отказывается.

Под соответствующим битом разрешения мы подразумеваем, например, бит разрешения на чтение, если процесс открывает объект только для чтения. Если процесс открывает объект для записи, должен быть установлен соответственно бит разрешения на запись для владельца (user-write).

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

4. Если соответствующий бит разрешения доступа для прочих пользователей установлен, доступ будет разрешен, иначе в доступе будет отказано.

Эти четыре проверки производятся в указанном порядке. Следовательно, если процесс является владельцем объекта IPC (шаг 2), доступ разрешается или запрещается на основе одних только разрешений пользователя (владельца). Разрешения группы при этом не проверяются. Аналогично, если процесс не является владельцем объекта IPC, но принадлежит к нужной группе, доступ разрешается или запрещается на основе разрешений группы - разрешения для прочих пользователей при этом не проверяются.

ПРИМЕЧАНИЕ

Согласно табл. 2.2, функция sem_open не использует флаги O_RDONLY, O_WRONLY, O_RDWR. В разделе 10.2, однако, будет сказано о том, что некоторые реализации Unix подразумевают наличие флага O_RDWR, потому что любое обращение к семафору подразумевает чтение и запись его значения.

2.5. Резюме

Три типа Posix IPC - очереди сообщений, семафоры и разделяемая память - идентифицируются их полными именами. Они могут являться или не являться реальными именами файлов в файловой системе, и это вызывает проблемы с переносимостью. Решение проблемы - использовать собственную функцию px_ipc_name. При создании или открытии объекта IPC требуется указать набор флагов, аналогичных указываемым при использовании функции open. При создании нового объекта IPC требуется указать разрешения для него, используя те же константы S_xxx, что и для функции open (табл. 2.3). При открытии существующего объекта IPC производится проверка разрешений процесса, аналогичная проверке при открытии файла.

Упражнения

1. Каким образом биты установки идентификатора пользователя (set-user-ID, SUID) и установки идентификатора группы (set-group-ID) (раздел 4.4 ) программы, использующей Posix IPC, влияют на проверку разрешений, описанную в разделе 2.4?

2. Когда программа открывает объект IPC, как она может определить, был ли создан новый объект IPC или производится обращение к существующему объекту?

ГЛАВА 3

3.1. Введение

Из имеющихся типов IPC следующие три могут быть отнесены к System V IPC, то есть к методам взаимодействия процессов, соответствующим стандарту System V:

■ очереди сообщений System V (глава 6);

■ семафоры System V (глава 11);

■ общая память System V (глава 14).

Термин «System V IPC» говорит о происхождении этих средств: впервые они появились в Unix System V. У них много общего: схожи функции, с помощью которых организуется доступ к объектам; также схожи формы хранения информации в ядре. В этой главе описываются общие для трех типов IPC черты.

Информация о функциях сведена в табл. 3.1.


Таблица 3.1. Функции System V IPC

ПРИМЕЧАНИЕ

Информация об истории разработки и развития функций System V IPC не слишком легко доступна. предоставляет следующую информацию: очереди сообщений, семафоры и разделяемая память этого типа были разработаны в конце 70-х в одном из филиалов Bell Laboratories в городе Колумбус, штат Огайо, для одной из версий Unix, предназначенной для внутреннего использования. Версия эта называлась Columbus Unix, или CB Unix. Она использовалась в так называемых системах поддержки операций - системах обработки транзакций - для автоматизации управления и ведения записей в телефонной компании. System V IPC были добавлены в коммерческую версию Unix System V. приблизительно в 1983 году.

3.2. Ключи типа key_t и функция ftok

В табл. 1.2 было отмечено, что в именах трех типов System V IPC использовались значения key_t. Заголовочный файл определяет тип key_t как целое (по меньшей мере 32-разрядное). Значения переменным этого типа обычно присваиваются функцией ftok.

Функция ftok преобразовывает существующее полное имя и целочисленный идентификатор в значение типа key_t (называемое ключом IPC - IPC key):

key_t ftok(const char *pathname, int id );
//Возвращает ключ IPC либо –1 при возникновении ошибки

На самом деле функция использует полное имя файла и младшие 8 бит идентификатора для формирования целочисленного ключа IPC.

Эта функция действует в предположении, что для конкретного приложения, использующего IPC, клиент и сервер используют одно и то же полное имя объекта IPC, имеющее какое-то значение в контексте приложения. Это может быть имя демона сервера или имя файла данных, используемого сервером, или имя еще какого-нибудь объекта файловой системы. Если клиенту и серверу для связи требуется только один канал IPC, идентификатору можно присвоить, например, значение 1. Если требуется несколько каналов IPC (например, один от сервера к клиенту и один в обратную сторону), идентификаторы должны иметь разные значения: например, 1 и 2. После того как клиент и сервер договорятся о полном имени и идентификаторе, они оба вызывают функцию ftok для получения одинакового ключа IPC.

Большинство реализаций ftok вызывают функцию stat, а затем объединяют:

■ информацию о файловой системе, к которой относится полное имя pathname (поле st_dev структуры stat);

■ номер узла (i-node) в файловой системе (поле st_ino структуры stat);

■ младшие 8 бит идентификатора (который не должен равняться нулю).

Из комбинации этих трех значений обычно получается 32-разрядный ключ. Нет никакой гарантии того, что для двух различных путей с одним и тем же идентификатором получатся разные ключи, поскольку количество бит информации в трех перечисленных элементах (идентификатор файловой системы, номер узла, идентификатор IPC) может превышать число бит в целом (см. упражнение 3.5).

ПРИМЕЧАНИЕ

Номер узла всегда отличен от нуля, поэтому большинство реализаций определяют константу IPC_PRIVATE (раздел 3.4) равной нулю.

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

Пример

Программа в листинге 3.1 принимает полное имя в качестве аргумента командной строки, вызывает функции stat и ftok, затем выводит значения полей st_dev и st_ino структуры stat и получающийся ключ IPC. Эти три значения выводятся в шестнадцатеричном формате, поэтому легко видеть, как именно ключ IPC формируется из этих двух значений и идентификатора 0x57.

Листинг 3.1 . Получение и вывод информации о файле и созданного ключа IPC
7 err_quit("usage: ftok ");
9 printf("st_dev: &lx, st_ino: %Ix, key: %x\n",
10 (u_long) stat.st_dev, (u_long) stat.st_ino,

Выполнение этой программы в системе Solaris 2.6 приведет к следующим результатам:

solaris %ftok /etc/system
st_dev: 800018, st_ino: 4a1b, key: 57018a1b
solaris %ftok /usr/tmp
st_dev: 800015, st_ino: 10b78, key: 57015b78
solaris %ftok /home/rstevens/Mail.out
st_dev: 80001f, st_ino: 3b03, key: 5702fb03

Очевидно, идентификатор определяет старшие 8 бит ключа; младшие 12 бит st_dev определяют следующие 12 бит ключа, и наконец, младшие 12 бит st_ino определяют младшие 12 бит ключа.

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

ПРИМЕЧАНИЕ

В FreeBSD используются младшие 8 бит идентификатора, младшие 8 бит st_dev и младшие 16 бит st_ino.

Учтите, что отображение, производимое функцией ftok, - одностороннее, поскольку часть бит st_dev и st_ino не используются. По данному ключу нельзя определить полное имя файла, заданное для вычислений.

3.3. Структура ipc_perm

Для каждого объекта IPC, как для обычного файла, в ядре хранится набор информации, объединенной в структуру.

uid_t uid; /*идентификатор пользователя владельца*/
gid_t gid; /*идентификатор группы владельца */
uid_t cuid; /*идентификатор пользователя создателя*/
gid_t cgid; /*идентификатор группы создателя*/
mode_t mode; /*разрешения чтения-записи*/
ulong_t seq; /*последовательный номер канала*/
key_t key; /* ключ IPC */

Эта структура вместе с другими переименованными константами для функций System V IPC определена в файле . В этой главе мы расскажем о полях структуры ipc_perm более подробно.


3.4. Создание и открытие каналов IPC

Три функции getXXX, используемые для создания или открытия объектов IPC (табл. 3.1), принимают ключ IPC (типа key_t) в качестве одного из аргументов и возвращают целочисленный идентификатор. Этот идентификатор отличается от того, который передавался функции ftok, как мы вскоре увидим. У приложения есть две возможности задания ключа (первого аргумента функций getXXX):

1. Вызвать ftok, передать ей полное имя и идентификатор.

2. Указать в качестве ключа константу IPCPRIVATE, гарантирующую создание нового уникального объекта IPC.

Последовательность действий иллюстрирует рис. 3.1.

Рис. 3.1. Вычисление идентификаторов IPC по ключам


Все три функции getXXX (табл. 3.1) принимают в качестве второго аргумента набор флагов oflag, задающий биты разрешений чтения-записи (поле mode структуры ipc_perm) для объекта IPC и определяющий, создается ли новый объект IPC или производится обращение к уже существующему. Для этого имеются следующие правила.

■ Ключ IPC_PRIVATE гарантирует создание уникального объекта IPC. Никакие возможные комбинации полного имени и идентификатора не могут привести к тому, что функция ftok вернет в качестве ключа значение IPC_PRIVATE.

■ Установка бита IPC_CREAT аргумента oflag приводит к созданию новой записи для указанного ключа, если она еще не существует. Если же обнаруживается существующая запись, возвращается ее идентификатор.

Одновременная установка битов IPC_CREAT и IPC_EXCL аргумента oflag приводит к созданию новой записи для указанного ключа только в том случае, если такая запись еще не существует. Если же обнаруживается существующая запись, функция возвращает ошибку EEXIST (объект IPC уже существует).

Комбинация IPC_CREAT и IPC_EXCL в отношении объектов IPC действует аналогично комбинации O_CREAT и O_EXCL для функции open.

Установка только бита IPC_EXCL без IPC_CREAT никакого эффекта не дает.

Логическая диаграмма последовательности действий при открытии объекта IPC изображена на рис. 3.2. В табл. 3.2 показан альтернативный взгляд на этот процесс.

Рис. 3.2. Диаграмма открытия объекта IPC


Обратите внимание, что в средней строке табл. 3.2 для флага IPC_CREAT без IPC_EXCL мы не получаем никакой информации о том, был ли создан новый объект или получен доступ к существующему. Для большинства приложений характерно создание сервером объекта IPC с указанием IPC_CREAT (если безразлично, существует ли уже объект) или IPC_CREAT | IPC_EXCL (если требуется проверка существования объекта). Клиент вообще не указывает флагов, предполагая, что сервер уже создал объект.

ПРИМЕЧАНИЕ

Функции System V IPC в отличие от функций Posix IPC определяют свои собственные константы IРС_ххх вместо использования O_CREAT и OEXCL, принимаемых стандартной функцией open (табл. 2.2).

Обратите также внимание на то, что функции System V IPC совмещают константы IРС_ххх с битами разрешений (описанными в следующем разделе) в едином аргументе oflag, тогда как для функции open и для Posix IPC характерно наличие двух аргументов: oflag, в котором задаются флаги вида О_ххх, и mode, определяющего биты разрешений доступа.


Таблица 3.2. Логика создания и открытия объектов IPC

Аргумент oflag Ключ не существует Ключ существует
Специальные флаги не установлены Ошибка, errno=ENOENT OK, открытие существующего объекта
IPC_CREAT OK, создается новая запись OK, открытие существующего
IPC CREAT|IPC_EXCL OK, создается новая запись Ошибка, errno=EEXIST

3.5. Разрешения IPC

При создании нового объекта IPC с помощью одной из функций getXXX, вызванной с флагом IPC_CREAT, в структуру ipc_perm заносится следующая информация (раздел 3.3):

1. Часть битов аргумента oflag задают значение поля mode структуры ipc_perm. В табл. 3.3 приведены биты разрешений для трех типов IPC (запись >>3 означает сдвиг вправо на три бита).

2. Поля cuid и cgid получают значения, равные действующим идентификаторам пользователя и группы вызывающего процесса. Эти два поля называются идентификаторами создателя.

3. Поля uid и gid структуры iрс_perm также устанавливаются равными действующим идентификаторам вызывающего процесса. Эти два поля называются идентификаторами владельца.


Таблица 3.3. Значения mode для разрешений чтения-записи IPC

Число (восьмеричное) Очередь сообщений Семафор Разделяемая память Описание
0400 MSG_R SEM_R SHM_R Пользователь - чтение
0200 MSG_W SEM_A SHM_W Пользователь - запись
0040 MSG R>>3 SEM_R>>3 SHM_R>>3 Группа - чтение
0020 MSG_W>>3 SEM_A>>3 SHM_W>>3 Группа - запись
0004 MSG_R>>6 SEM_R>>6 SHM_R>>6 Прочие - чтение
0002 MSG_W>>6 SEM_A>>6 SHM_W>>6 Прочие - запись

Идентификатор создателя изменяться не может, тогда как идентификатор владельца может быть изменен процессом с помощью вызова функции ctlXXX для данного механизма IPC с командой IPC_SET. Три функции ctlXXX позволяют процессу изменять биты разрешений доступа (поле mode) объекта IPC.

ПРИМЕЧАНИЕ

В большинстве реализаций определены шесть констант: MSG_R, MSG_W, SEM_R, SEM_A, SHM_R и SHM_W, показанные в табл. 3.3. Константы эти определяются в заголовочных файлах , и . Однако стандарт Unix 98 не требует их наличия. Суффикс А в SEM_A означает «alter» (изменение).

Тройка функций getXXX не используют стандартную маску создания файла Unix. Разрешения очереди сообщений, семафора и разделяемой памяти устанавливаются в точности равными аргументу функции.

Posix IPC не дает создателю IPC возможности изменить владельца объекта. В Posix нет аналогов команды IPC_SET. Однако в Posix IPC имя объекта принадлежит файловой системе, и потому владелец может быть изменен привилегированным пользователем с помощью команды chown.

Когда какой-либо процесс предпринимает попытку доступа к объекту IPC, производится двухэтапная проверка: первый раз при открытии файла (функция getXXX) и затем каждый раз при обращении к объекту IPC:

1. При установке доступа к существующему объекту IPC с помощью одной из функций getXXX производится первичная проверка аргумента oflag, вызывающего функцию процесса. Аргумент не должен указывать биты доступа, не установленные в поле mode структуры ipc_perm (нижний квадрат на рис. 3.2). Например, процесс-сервер может установить значение члена mode для своей очереди входящих сообщений, сбросив биты чтения для группы и прочих пользователей. Любой процесс, попытавшийся указать эти биты в аргументе oflag функции msgget, получит ошибку. Надо отметить, что от этой проверки, производимой функциями getXXX, мало пользы. Она подразумевает наличие у вызывающего процесса информации о том, к какой группе пользователей он принадлежит: он может являться владельцем файла, может принадлежать к той же группе или к прочим пользователям. Если создающий процесс сбросит некоторые биты разрешений, а вызывающий процесс попытается их установить, функция getXXX вернет ошибку. Любой процесс может полностью пропустить эту проверку, указав аргумент oflag, равный 0, если заранее известно о существовании объекта IPC.

2. При любой операции с объектами IPC производится проверка разрешений для процесса, эту операцию запрашивающего. Например, каждый раз когда процесс пытается поместить сообщение в очередь с помощью команды msgsnd, производятся нижеследующие проверки (при получении доступа последующие этапы пропускаются).

□ Привилегированному пользователю доступ предоставляется всегда.

□ Если действующий идентификатор пользователя совпадает со значением uid или cuid объекта IPC и установлен соответствующий бит разрешения доступа в поле mode объекта IPC, доступ будет разрешен. Под соответствующим битом разрешения доступа подразумевается бит, разрешающий чтение, если вызывающий процесс запрашивает операцию чтения для данного объекта IPC (например, получение сообщения из очереди), или бит, разрешающий запись, если процесс хочет осуществить ее.

□ Если действующий идентификатор группы совпадает со значением gid или cgid объекта IPC и установлен соответствующий бит разрешения доступа в поле mode объекта IPC, доступ будет разрешен.

□ Если доступ не был разрешен на предыдущих этапах, проверяется наличие соответствующих установленных битов доступа для прочих пользователей.

3.6. Повторное использование идентификаторов

Структура ipc_perm (раздел 3.3) содержит переменную seq, в которой хранится порядковый номер канала. Эта переменная представляет собой счетчик, заводимый ядром для каждого объекта IPC в системе. При удалении объекта IPC номер канала увеличивается, а при переполнении сбрасывается в ноль.

ПРИМЕЧАНИЕ

В этом разделе мы описываем характерную для SVR4 реализацию. Стандарт Unix 98 не исключает использование других вариантов.

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

Идентификатор IPC возвращается одной из функций getXXX: msgget, semget, shmget. Как и дескрипторы файлов, идентификаторы представляют собой целые числа, имеющие в отличие от дескрипторов одинаковое значение для всех процессов. Если два неродственных процесса (клиент и сервер) используют одну очередь сообщений, ее идентификатор, возвращаемый функцией msgget, должен иметь одно и то же целочисленное значение в обоих процессах, чтобы они получили доступ к одной и той же очереди. Такая особенность дает возможность какому-либо процессу, созданному злоумышленником, попытаться прочесть сообщение из очереди, созданной другим приложением, последовательно перебирая различные идентификаторы (если бы они представляли собой небольшие целые числа) и надеясь на существование открытой в текущий момент очереди, доступной для чтения всем. Если бы идентификаторы представляли собой небольшие целые числа (как дескрипторы файлов), вероятность найти правильный идентификатор составляла бы около 1/50 (предполагая ограничение в 50 дескрипторов на процесс).

Для исключения такой возможности разработчики средств IPC решили расширить возможный диапазон значений идентификатора так, чтобы он включал вообще все целые числа, а не только небольшие. Расширение диапазона обеспечивается путем увеличения значения идентификатора, возвращаемого вызывающему процессу, на количество записей в системной таблице IPC каждый раз, когда происходит повторное использование одной из них. Например, если система настроена на использование не более 50 очередей сообщений, при первом использовании первой записи процессу будет возвращен идентификатор 0. После удаления этой очереди сообщений при попытке повторного использования первой записи в таблице процессу будет возвращен идентификатор 50. Далее он будет принимать значения 100, 150 и т. д. Поскольку seq обычно определяется как длинное целое без знака (ulong - см. структуру ipc_perm в разделе 3.3), возврат к уже использовавшимся идентификаторам происходит, когда запись в таблице будет использована 85899346 раз (2³²/50 в предположении, что целое является 32-разрядным).

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

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

Листинг 3.2. Вывод идентификатора очереди сообщений десять раз подряд
7 msqid=Msgget(IPC_PRIVATE, SVMSG_MODE|IPC_CREAT);
8 printf("msqid = %d\n", msqid);
9 Msgctl(msqid, IPC_RMID, NULL);

При очередном прохождении цикла msgget создает очередь сообщений, a msgctl с командой IPC_RMID в качестве аргумента удаляет ее. Константа SVMSG_MODE определяется в нашем заголовочном файле unpipc.h (листинг В.1) и задает разрешения по умолчанию для очереди сообщений System V. Вывод программы будет иметь следующий вид:

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

3.7. Программы ipcs и ipcrm

Поскольку объектам System V IPC не сопоставляются имена в файловой системе, мы не можем просмотреть их список или удалить их, используя стандартные программы ls и rm. Вместо них в системах, поддерживающих эти типы IPC, предоставляются две специальные программы: ipcs, выводящая различную информацию о свойствах System V IPC, и ipcrm, удаляющая очередь сообщений System V, семафор или сегмент разделяемой памяти. Первая из этих функций поддерживает около десятка параметров командной строки, управляющих отображением информации о различных типах IPC. Второй (ipcrm) можно задать до шести параметров. Подробную информацию о них можно получить в справочной системе.

ПРИМЕЧАНИЕ

Поскольку System V IPC не стандартизуется Posix, эти команды не входят в Posix.2. Они описаны в стандарте Unix 98.

3.8. Ограничения ядра

Большинству реализаций System V IPC свойственно наличие внутренних ограничений, налагаемых ядром. Это, например, максимальное количество очередей сообщений или ограничение на максимальное количество семафоров в наборе. Характерные значения этих ограничений приведены в табл. 6.2, 11.1 и 14.1. Большая часть ограничений унаследована от исходной реализации System V.

ПРИМЕЧАНИЕ

Раздел 11.2 книги и глава 8 описывают реализацию очередей сообщений, семафоров и разделяемой памяти в System V. Некоторые из этих ограничений описаны уже там.

К сожалению, некоторые из накладываемых ограничений достаточно жестки, поскольку они унаследованы от исходной реализации, базировавшейся на системе с небольшим адресным пространством (16-разрядный PDP-11). К счастью, большинство систем позволяют администратору изменять некоторые из установленных по умолчанию ограничений, но необходимые для этого действия специфичны для каждой версии Unix. В большинстве случаев после внесения изменений требуется перезагрузка ядра. К сожалению, в некоторых реализациях для хранения некоторых параметров до сих пор используются 16-разрядные целые, а это уже устанавливает аппаратные ограничения.

В Solaris 2.6, например, таких ограничений 20. Их текущие значения можно вывести на экран, используя команду sysdef. Учтите, что вместо реальных значений будут выведены нули, если соответствующий модуль ядра не загружен (то есть средство не было ранее использовано). Это можно исключить, добавив к файлу /etc/system любой из нижеследующих операторов. Файл /etc/system считывается в процессе перезагрузки системы:

set msgsys:msginfo_msgseg = значение
set msgsys:msginfo_msgssz = значение
set msgsys:msginfo_msgtql = значение
set msgsys:msginfo_msgmap = значение
set msgsys:msginfo_msgmax = значение
set msgsys:msginfo_msgmnb = значение
set msgsys:msginfo_msgmni = значение

set semsys:seminfo_semopm = значение
set semsys:seminfo_semume = значение
set semsys:seminfo_semaem = значение
set semsys:seminfo_semmap = значение
set semsys:seminfo_semvmx = значение
set semsys:seminfo_semmsl = значение
set semsys:seminfo_semmni = значение
set semsys:seminfo_semmns = значение
set semsys:seminfo_semmnu = значение

set shmsys:shminfo_shmmin = значение
set shmsys:shminfo_shmseg = значение
set shmsys:shminfo_shmmax = значение
set shmsys:shminfo_shmmni = значение

Последние шесть символов имени слева от знака равенства представляют собой переменные, перечисленные в табл. 6.2, 11.1 и 14.1.

В Digital Unix 4.0B программа sysconfig позволяет узнать или изменить множество параметров и ограничений ядра. Ниже приведен вывод этой команды, запущенной с параметром –q. Команда выводит текущие ограничения для подсистемы ipc. Некоторые строки в выводе, не имеющие отношения к средствам IPC System V, были опущены:

alpha % /sbin/sysconfig –q ipc

Для этих параметров можно указать другие значения по умолчанию, изменив файл /etc/sysconfigtab. Делать это следует с помощью программы sysconfigdb. Этот файл также считывается в процессе начальной загрузки системы.

3.9. Резюме

Первым аргументом функций msgget, semget и shmget является ключ IPC System V. Эти ключи вычисляются по полному имени файла с помощью системной функции ftok. В качестве ключа можно также указать значение IPCPRIVATE. Эти три функции создают новый объект IPC или открывают существующий и возвращают идентификатор System V IPC - целое число, которое потом используется для распознавания объекта в прочих функциях, имеющих отношение к IPC. Эти идентификаторы имеют смысл не только в рамках одного процесса (как дескрипторы файлов), но и в рамках всей системы. Они могут повторно использоваться ядром, но лишь спустя некоторое время.

С каждым объектом System V IPC связана структура ipc_perm, содержащая информацию о нем, такую как идентификатор пользователя владельца, идентификатор группы, разрешения чтения и записи и др. Одним из отличий между System V и Posix IPC является то, что для объекта IPC System V эта информация доступна всегда (доступ к ней можно получить с помощью одной из функций XXXctl с аргументом IPC_STAT), а в Posix IPC доступ к ней зависит от реализации. Если объект Posix IPC хранится в файловой системе и мы знаем его имя в ней, мы можем получить доступ к этой информации, используя стандартные средства файловой системы.

При создании нового или открытии существующего объекта System V IPC функции getXXX передаются два флага (IPC_CREAT и IPC_EXCL) и 9 бит разрешений.

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

Упражнения

1. Прочитайте о функции msgctl в разделе 6.5 и измените программу в листинге 3.2 так, чтобы выводился не только идентификатор, но и поле seq структуры ipc_perm.

2. Непосредственно после выполнения программы листинга 3.2 мы запускаем программу, создающую две очереди сообщений. Предполагая, что никакие другие приложения не использовали очереди сообщений с момента загрузки системы, определите, какие значения будут возвращены функцией msgget в качестве идентификаторов очередей сообщений.

3. В разделе 3.5 было отмечено, что функции getXXX System V IPC не используют маску создания файла. Напишите тестовую программу, создающую канал FIFO (с помощью функции mkfifо, описанной в разделе 4.6) и очередь сообщений System V, указав для обоих разрешение 666 (в восьмеричном формате). Сравните разрешения для созданных объектов (FIFO и очереди сообщений). Перед запуском программы удостоверьтесь, что значение umask отлично от нуля.

4. Серверу нужно создать уникальную очередь сообщений для своих клиентов. Что предпочтительнее: использовать какое-либо постоянное имя файла (например, имя сервера) в качестве аргумента функции ftok или использовать ключ IPC_PRIVATE?

5. Измените листинг 3.1 так, чтобы выводился только ключ IPC и путь к файлу. Запустите программу find, чтобы вывести список всех файлов вашей файловой системы, и передайте вывод вашей только что созданной программе. Скольким именам файлов будет соответствовать один и тот же ключ?

6. Если в вашей системе есть программа sar (system activity reporter - информация об активности системы), запустите команду

На экран будет выведено количество операций в секунду с очередями сообщений и семафорами, замеряемыми каждые 5 секунд 6 раз.

Примечания:

Многие пользователи локальных сетей часто не подозревают что их диски являются сетевыми ресурсами к которым можно подключится, упоминаются как скрытые административные и общие ресурсы C$, ADMIN$, FAX$, IPC$, PRINT$. Их нужно отключить если они вам не нужны!

Виды общих сетевых ресурсов в Windows XP/200

По умолчанию в Windows XP/2000 могут быть созданы следующие скрытые административные общие ресурсы:

  1. корневые разделы или тома C$ (D$, E$, F$ и т.д. );
  2. корневой каталог операционной системы ADMIN$;
  3. общий ресурс FAX$;
  4. общий ресурс IPC$;
  5. общий ресурс PRINT$.

Для корневых разделов и томов в качестве имени общего ресурса используется имя диска, к которому добавляется символ «$ ». Например, для доступа к дискам C и D будут созданы общие ресурсы C$ и D$ .

Корневой каталог операционной системы ( %SYSTEMROOT% ) – это каталог, в котом установлена операционная система Windows. Общий ресурс ADMIN$ предоставляет администраторам доступ к этой папке по сети.

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

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

Общий ресурс PRINT$ используется для удаленного администрирования принтеров.

Если удалить скрытые административные ресурсы, созданные операционной системой (например, ADMIN$ или C$ ), то после перезагрузки компьютера или перезапуска службы «Сервер» они будут созданы повторно. Если удалить скрытые административные ресурсы, созданные пользователями, то после перезагрузки компьютера они повторно созданы не будут. Microsoft Windows XP Home Edition не создает скрытые административные общие ресурсы.

Подключение к общим сетевым ресурсам в Windows XP/2000

Для подключения к скрытым административным и общим сетевым ресурсам можно использовать стандартную команду Windows XP/2000 net use :

Команда net use используется для подключения и отключения от сетевых ресурсов и для вывода сведений о текущих подключениях к таким ресурсам. Если сетевой ресурс является текущим диском или его использует какое-либо работающее приложение, отключиться от такого ресурса невозможно.

Ниже приводится пример использования команды net use для подключения к стандартному общему ресурсу C$ , компьютера под управлением Windows 2000, с полным именем Pro2000 , расположенного в локальной сети:

Команда net use выполнена успешно под именем пользователя Администратор и пустым паролем! В большинстве случаев после установки Windows, пароль на учетную запись с именем Администратор, создаваемую по умолчанию, забывают или просто не хотят ставить, а бывает так, что во время установки создавалась другая административная учетная запись, а учетная запись с именем Администратор, созданная по умолчанию, осталась без внимания!

C:\> cd /d q: Q:\> dir Том в устройстве Q не имеет метки. Серийный номер тома: 407D-A72A Содержимое папки Q:\ 13.03.2012 08:46 0 AUTOEXEC.BAK 13.03.2012 08:57 Documents and Settings 17.06.2012 08:34 Intel 01.04.2012 04:02 MySoft 17.06.2012 11:35 NC 18.06.2012 10:10 OpenSSL-Win32 18.06.2012 10:08 Program Files 25.06.2012 15:48 PUBLIC 18.05.2012 10:53 rms 29.04.2012 10:48 Temp 11.06.2012 22:28 WINDOWS 1 файлов 0 байт 10 папок 1 919 221 760 байт свободно Q:\>

После подключения ресурса C$ и его ассоциации с буквой диска, ресурс C$ будет доступен в вашем проводнике и с ним можно будет работать так, как с обычным локальным диском, ну, а дальше всё будет зависеть от ваших способностей и фантазии...

ВНИМАНИЕ!!! Общие ресурсы будут доступны только в том случае когда включена/запущена служба "Сервер", а если вы не собираетесь расшаривать свои ресурсы, то лучше её не просто остановить, а отключить совсем. Служба "Сервер" - Обеспечивает поддержку общий доступ к файлам, принтерам и именованным каналам для данного компьютера через сетевое подключение. Если служба остановлена, такие функции не удастся выполнить. Если данная служба неразрешена, не удастся запустить любые явно зависимые службы.

Приведённый выше пример наглядно демонстрирует уязвимость неприкрытых сетевых ресурсов и учетной записи Администратор, созданную по умолчанию с пустым паролем! Во избежание образования подобных щелей и как результат регулярной переустановки Windows с последующим преданием анафеме Билла Гейтса нужно просто изначально прикрывать, так сказать, все щели и дыры!!!

Отключение/удаление общих сетевых ресурсов

Самый простой способ это отключить службу "Сервер", но, некоторые службы и программы нуждаются в её поддержке, в таком случае отключение службы "Сервер" нам не подходит.

Для отключения административных и общих сетевых ресурсов (C$, ADMIN$, FAX$, IPC$, PRINT$ ) в Windows XP/2000 нужно:

ПРИМЕЧАНИЕ! В Windows 2000 параметр AutoShareWks добавлять не требуется.

После перезагрузки ПК будут удалены все общие сетевые ресурсы, за исключением одного IPC$ , его нельзя удалить:

Особый общий ресурс IPC$

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

Особый общий ресурс IPC$ обязателен для работы службы серверов и не может быть удален. Просмотреть список текущих общих сетевых ресурсов можно командой net share

Повторимся, что воизбежание образования щелей в общих сетевых ресурсах и как результат регулярной переустановки Windows с последующим преданием анафеме Билла Гейтса нужно просто изначально прикрывать, так сказать, все щели и дыры!!!