ed0 – адаптер сети Ethernet. Он входит в частную сеть 172.30.0.0. адрес 00.00.c0.54.77 – это первый в списке МАС – адресов (media – access control – контроль доступа к носителю) данный сетевой карты. Через этот интерфейс прошло 40841 входных пакетов и 5793 выходных. MTU составляет 1500 – максимальное значение для сетей Ethernet.
Интерфейс thn0 – телефонный канал, по которому связь осуществляется по протоколу PPP. Он входит в сеть 205.184.142.0. MTU =1500
Интерфейс slo – телефонный канал, по которому связь осуществляется по протоколу SLIP (Serial Line Internet Protocol) не используется, устарел.
Lo0 – развратный интерфейс;
Faihh - псевдоустройство для преобразования IPV6 в IPV4.
В сочетании с опцией - и можно использовать опции - в (количество байтов,
прошедших через интерфейс в обе стороны) и-d(количество отброшенных пакетов).
rl- Realtes 8129/8139, драйвер Fast Ethernet
Маршрутная таблица
Bsd: $ netstdt - rn, r - routing; n- чтобы получить не символические имена, а адреса IP.
Routing tables
Internet:
Destination Gateway Flags Refs Use Netif Expire
Default 163.179.44.41 u6sc 2 0 tun 0
127.0.Uh 1 34 lo 0
163.179.44171 UH 3 0 tun 0
172.30 link#1 UC 0 0 ed 0
172.30.0.1 0:0:c0:54:53:73 UHLW 0 132 lo 0
![]() |
Иллюстрация к таблице
Default- коды неточного маршрута,
Refs - количество активных пользователей,
Use - количество по маршруту,
MAC - адрес сетевой карты – флаг L.
Destination - пункт назначения маршрута - это может быть конкретный хост, есть или маршрут по умолчанию.
Flags - флаги
1 U - маршрут задействован(“UP”)
2 H - маршрут к хосту (если он отсутствует, то речь идет о маршруте к сети или под сети)
3 С - не прямой маршрут, т. е. к пункту назначения надо добираться через промежуточный маршрутизатор или шлюз.
Флаг H означает, что адрес представляет собой полный IP - адрес. Если же H отсутствует, то значит в первой колонке указан адрес сети. Флаг C показывает, достижим ли адрес, проставленный в первой колонке непосредственно с данного хоста, или надо пройти через промежуточный маршрут и затор. Для некоторых маршрутов могут быть одновременно установлены флаги C и H
![]() |
H2 выступает в роли шлюза к H3.
Хост H3 соединен с H2 по PPP линиям с сетевым адресом 192.168.2.
Маршрут H3 в маршрутной таблице H1:
Destination Gateway Flags Refs Use Netif Expire
192.168.UCH 0 0 ed0
H установлен, т. к. 192.168.2.2- полный адрес хоста C - т. к. нет у H1 прямого соединения с H3, и H1 должен идти через хост H2(172.20.10.2).
Статистика протоколов
С помощью Netstat можно получить статистику протоколов. Опция - s обеспечивает выдачу по протоколам IP, ICMP, IGMP, UDP и TCP.
Если нужен один протокол, то используется опция - p.
Например, для UDP следует ввести следующую команду:
$ netstat - sp udp;
udp:
82 datagraws reciived; получено диаграмм;
0 with incomplete header; с неполным заголовком;
0 with bad data length field; с неправильным значением в поле длины данных;
0 with bad checksum; с неправильной контрольной суммой
1 dropped due to no socket; отброшено из-за отсутствия сокета
0 broadest/multicast datagrams dropped due no socket; отброшено широковещание групповых дейтаграмм из-за отсутствия сокета
0 dropped due to full socket buffers; отброшено из-за переполненного буфера сокета
0 not for heshed pep; не для хешированого блока управления
81delivered; доставлено
82 datagrams output; отправлено дейтаграмм.
можно отметить печать строк с нулевыми значениями, если задать опцию - s: - ssp udp.
Статистика, проводимая с помощью программы netstat, показывает, что доставка не по порядку и получение дубликатов пакетов проходит часть.
$netstat - ssp tcp;
tcp:
446 packets sent Пакетов послано
190 data packets (40474 bytes) пакетов данных(40474)
213 ack-only packets (166 delayed) пакетов, содержащих только ACK
18 window update packets пакетов с обновлением окна
32 control packets контрольных пакетов
405 packets reccived пакетов принято
193acks (for 40488 bytes) аск (на 40488 байт)
12 duplicate acks повторных аск
302 packets (211353 bytes) receved in segnense пакета получено по порядку
10 completely duplicate packets (4380 bytes) полных дубликатов
22 out-of-order packets (16114 bytes) не по порядку
2 window update packets с обновлением окна
20 connection requests запросов на соединение
2 connect accept приема соединения
13 connection established (including accept) соединение установлено
22 connections closed (including 0 drops) соединение закрыто
3 connections updated cached RTT on close соединение при закрытии обновили RTT в КЭШе
3 connections updated cached RTT variance Соединение при закрытии обновили дисперсию в КЭШе
2 embryonic connections dropped эмбриональных соединений сброшено
193 segments updated rtt (of 201 attempts) сегмент обновили rtt (из 201 попытки)
31 correct ACK header prdictions правильное предсказание заголовка АСК
180 correct data packet header predictions правильное предсказание заголовка пакета с данными
Процессы
Программы в UNIX выполняются на уровне процессов. От оптимальной настройки подсистемы управления процессами и числа одновременно выполняющихся процессов зависит загрузка ресурсов процессора, что в свою очередь непосредственно влияет на производительность системы в целом. Базовый набор услуг, определяемый интерфейсом системных вызовов, предоставляется ядром ОС. Это основные операции по работе с файлами, управление процессами и памятью, поддержка межпроцессорного взаимодействия. От того, какие процессы выполняются в системе, зависит, является ли она сервером базы данных и сервером сетевого доступа, средством проектирования или вычислительным сервером.
Программой называется совокупность файлов: исходных текстов, объектных модулей, исполняемых файлов. Для обеспечения запуска программы на выполнение ОС должна сначала создать окружение ил среду выполнения задачи, куда относятся ресурсы памяти, возможность доступа к устройствам ввода/вывода и другим системным ресурсам, включая услуг ядра. Это окружение получило название процесса. Процесс можно представить как совокупность данных ядра системы, необходимых для описания образа программы в памяти и управления ее выполнением. Процесс также – это программа в стадии ее выполнения, т. к. все выполняющиеся программы представлены в UNIX в виде процессов. Процесс – это совокупность инструкций, выполняемых процессом, данных и информации о выполняемой задаче: размещенная память, открытые файлы и статус процесса. В то же время программа может породить более одного процесса. Простые программы, например, cat(1) при выполнении представлены одним процессом, сложные – Telnet, порождают в системе несколько одновременно выполняющихся процессов – в смысле многозадачности. Выполнение процесс заключается в точном следовании набору инструкций, которые никогда не передают управление набору инструкций другого процесса. Процесс считывает и записывает данные в раздел данных и в стек, но ему недоступны данные и стеки других процессов. В то же время процессы имеют возможность обмениваться друг с другом данными с помощью системы межпроцессного взаимодействия. Его средствами являются сигналы (signals), каналы (pipes), разделяемая память (shared memory), семафоры (semaphores), сообщения (messages) и файлы. В остальном процессы изолированы друг от друга.
Типы процессов
Системные процессы .
Системные процессы являются частью ядра, всегда расположены в ОЗУ и запускаются особым образом при инициализации ядра системы. Выполняемые инструкции и данные этих процессов находятся в ядре системы, таким образом они могут вызывать функции и обращаться к данным, недоступным для остальных процессов. Системными процессами являются: shed (диспетчер свопинга), vhand (диспетчер страничного замещения), bdfflush (диспетчер буферного кэша) и kmadaemon (диспетчер памяти ядра). Системный процесс init является прародителем всех остальных процессов в UNIX, но не является частью ядра. Его запуск происходит из исполняемого файла (/etc/init).
Демоны.
Демоны – это интерактивные процессы, которые запускаются путем загрузки в память исполняемых файлов, и выполняются в фоновом режиме. Демоны запускаются после инициализации ядра при инициализации системы, и обеспечивают работу различных подсистем ОС: системы терминального доступа, системы печати, системы сетевого доступа, сетевых услуг. Демоны не связаны ни с одним пользовательским сеансом работы и не могут непосредственно управляться пользователем. Большую часть времени демоны ожидают пока тот или иной процесс запросит определенную услугу: доступ к файловому архиву или печать документов.
Прикладные процессы
К прикладным процессам относятся все остальные процессы, выполняющиеся в системе, как правило, порожденные в рамках пользовательского сеанса работы. Например, запуск команды ls(1) породит прикладной процесс просмотра файлов, процессов, которые выполняются. Основной командный интерпретатор ( login sheel ), обеспечивает работу в UNIX, он запускается сразу после регистрации в системе, а после завершения работы отключается от системы. Пользовательские процессы могут выполняться как в интерактивном, так и фоновом режимах, но время их жизни ограничено сеансом пользователя. Интерактивные процессы монопольно владеют терминалом, пока такой процесс не завершит свое выполнение, например, ps(1). В то же время интерпретатор sheel считывает пользовательский ввод и запускает задачи.
Атрибуты процессов
Каждый процесс имеет уникальный идентификатор PID, позволяющий ядру системы различать процессы. Когда создается новый процесс, ядро присваивает ему следующий свободный идентификатор по нарастающей до максимально возможного. Когда процесс завершает свою работу, ядро освобождает занятый им идентификатор, (0…65535)=216.
Идентификатор родительского процесса (PPID)
Parent Process ID
Идентификатор процесса, породившего данный процесс.
Приоритет процесса ( Nice Number)
С одной стороны это относительный приоритет процесса, учитываемый планировщиком при определении очередности запуска. Фактическое распределение процессорных ресурсов определяется приоритетом выполнения, зависящим от нескольких факторов, в частности, от заданного относительного приоритета. Относительный приоритет не применяется системой на всем протяжении жизни процесса, но может быть изменен пользователем или администратором. Приоритет выполнения динамически обновляется ядром.
Реальный (RID) и эффективный (EUID) идентификаторы
пользователя
Реальный идентификатором пользователя данного процесса является идентификатор пользователя, запустившего процесс. Эффективный идентификатор служит для определения прав доступа процесса к системным ресурсам, в первую очередь к ресурсам файловой системы. Обычно RID и EUID эквивалентны, т. е. процесс имеет в системе те же права, что и пользователь, запустивший его. Существует возможность задать процессу более широкие права, чем права пользователя путем установки флаги SUID, когда эффективному идентификатору присваивается значение идентификатора владельца исполняемого файла.
Реальный (RGID) и эффективный (EGID) идентификаторы группы
RGID равен идентификатору первичной ил текущей группы пользователя, запустившего процесс. EGID служит для определения прав доступа к системным ресурсам по классу доступа группы. Возможна установка EGID равным идентификатору группы владельца исполняемого файла ( флаг SGID).
Жизненный путь процесса
Процесс в UNIX создается системным вызовом fork(2). Процесс, сделавший вызов fork(2), называется родительским, а вновь созданный процесс – дочерним. Новый процесс имеет те же инструкции и данные, что и его родитель. Выполнение родительского и дочернего процесса начнется с одной и той же инструкции, следующей за вызовом fork(2). Отличаются они только PID. Для запуска новой программы процесс должен выполнить системный вызов exec(2). При этом новый процесс не порождается, а исполняемый код дочернего процесса полностью замещается кодом запускаемой программы. Окружение же новой программы во многом сохраняется, в частности сохраняются значения переменных окружения, назначения стандартных потоков ввода/вывода, вывода сообщений об ошибках и приоритет процесса. Запуск на выполнение новой программы часто связан с порождением нового процесса, таким образом, сначала процесс выполняет вызов fork(2), порождая дочерний процесс, который затем выполняет exec(2), полностью замещаясь новой программой. Пусть пользователь, работая в командном интерпретаторе shell, запускает ls(1). Текущий процесс (shell) делает вызов fork(2), порождая вторую копию shell. Порожденный shell вызывает exec(2), указывая в качестве параметра имя исполняемого файла, образ которого необходимо загрузить в память вместо кода shell. Код ls(1) размещает код порожденного shell, и утилита ls(1) начинает выполняться. По завершении работы ls(1) созданный процесс “умирает”. Пользователь вновь возвращается в командный режим
![]() |
$ ps(1) –ef / head –20
UID PID PPID C CMD
1 user 1 sh пользователь работает в командном режиме
2 user 1 sh
3 user 1 sh
4 user 1 sh
5 user 1 ls
6 user 1 sh
Процедура запуска новой программы называется fork-and-exec. Бывают ситуации, когда достаточно одного вызова fork(2) без последующего exec(2). В этом случае исполняемый код родительского процесса должен содержать логическое ветвление для родительского и дочернего процессов. Прародителем всех процессов является процесс init(1M), который также называемый распределителем процессов. init(1M) – это демон, неинтерактивная программа обеспечивающая доступ по сети, печать, электронная почта, возможность терминального входа.
Сигналы
Сигналы являются способом передачи от одного процесса к другому или от ядра ОС к процессу уведомления о возникновении определенного события. Сигналы рассматриваются как простейшая форма межпроцессорного взаимодействия. Сигналы похожи на программные прерывания, когда нормальное выполнение процесса прерывается. Например, если процесс производит деление на 0, ядро посылает ему сигнал SIGFPE; при нажатии клавиш прерывания - <Del> или <Ctrl>+<C>,текущему процессу посылается сигнал SIGINT.
Для отправления сигнала служит команда kill(1):
kill sig_no pid,
Где sig_no – номер или символическое название сигнала, а pid – идентификатор процесса, которому посылается сигнал. Администратор системы может посылать сигналы любым процессам, обычный же пользователь может посылать сигналы только процесса, владельцем которых он является. PID и EUID процесса, посылающего сигнал, должны совпадать с идентификатором пользователя. Например, процессу, который только что запустили в фоновом режиме, нужно послать сигнал завершения выполнения SIGTERM; для этого нужно:
$ long_program & Запуск программы в фоновом режиме
$ kill $! По умолчанию команда kill(1) посылает сигнал SIGTERM; переменная $! Содержит PID последнего процеса, запущенного в фоновом режиме
При получении сигнала процесс имеет три варианта действий для выбора:
1. Он может игнорировать сигнал, но нельзя игнорировать сигналы, вызванные аппаратной частью, при делении на 0 или ссылки на недопустимые области памяти.
2. Процесс может потребовать действия по умолчанию, это сводится к завершению выполнения процесса.
3. Процесс может перехватить сигнал и самостоятельно обработать его, т. е. например, перехват сигнала SIGINT позволит процессу удалить созданные или временные файлы. Сигналы SIGKILL и SIGSTOP нельзя ни перехватить, ни игнорировать.
По умолчанию команда kill(1) посылает сигнал с номером 15 – SIGTERM – завершение выполнения процесса, получившего сигнал. Иногда процесс продолжает существовать и после отправления сигнала SIGTERM. В этом случае можно применить более жесткое средство – послать сигналу SIGKILL с номером (9), т. к. этот сигнал нельзя ни перехватить, ни игнорировать:
$kill – 9pid
Иногда процесс не исчезает и в этом случае:
1. Процессы-зомби, т. е. процессы, от которых осталась лишь запись в системной таблице, удалить его можно только перезапуском ОС. В больших количествах они переполняют таблицы процессов.
2. Процессы, ожидающие недоступные ресурсы NFS( Network File System), например, записывающие данные в файл файловой системы в ПК удаленного доступа, отключенного от сети.
3. Процессы, ожидающие завершение операции с устройством.
Сигналы могут использоваться не только для завершения, но и для, например, считывания базы данных с сервера: SIGHUP посылается серверу DNS (named(1M)).
Взаимодействие между процессами
С одной стороны процессы изолированы друг от друга, находясь в разных адресных пространствах. С другой стороны, они должны взаимодействовать:
1. Передавать данные
2. Совместно использовать данные
3. Извещать друг друга о наступлении какого-либо события
Механизмы взаимодействия сводятся к использованию:
1. Сигналов
2. Каналов,
например, Cat myfileçwc оба процесса создаются shell
Стандартный вывод программы cat(1), которая выводит содержимое файла myfile, передается на стандартный ввод программы wc(1), которая подсчитывает количество строк, строк и символов. В результате получим
12
строк слов символов
Каналы могут использоваться для взаимодействия только родственных процессов.
Использовался программный канал, который обеспечил однонаправленную передачу данных между двумя процессами.
3. FIFO – очень похож на каналы, но это именованный канал, как файл, например, программа “сервер”.
$mknod name p – создание FIFO из командной строки.
где p программма ls покажет в первой позиции.
После создания FIFO может быть открыт на запись и чтение, причем и то и другое может происходитьв разных процессах.
Организация каналов
Для создания канала используются системный вызов pipe(2);
int pipe(int*fildes); или int pipe(int filedes[2]);
fildes – переменная, может быть filedes.
Системный вызов pipe(2) возвращает два файловых дескриптора: fildes[0] для записи в канал, fildes[1] – для чтения из канала. Если один процесс записывает данные в fildes[0], то другой процесс может получить эти данные из fildes[1]. Сложность в том, как второй процесс сможет получить сам файловый дескриптор fildes[1]. В случае неудачи возвращение – 1.
При создании процесса дочерний процесс наследует все назначенные файловые дескрипторы родительского процесса. Доступ к дескрипторам fildes канала может получить сам процесс, вызвавший pipe(2) и его дочерние процессы. После создания канала с ним можно работать с помощью системных вызовов read write.
![]() |
Рис. Создане канала между задачами cat(1) и wc(1)
Если в канал записать три сообщения, то считываться они будут в том же порядке
Каналы создаются заново и после обращения к ним процесса уничтожаются.
Буферизация данных в канале стандартно осуществляется путем выделения дискового пространства в структуре файловой системы. Таким образом, запись и чтение связаны с дисковым вводом/ выводом, что сказывается на его производительности. Современные ОС (серверные) обеспечивают работу каналов через специальную файловую систему HPPS( High Performance Pipe System). С ее помощью данные буферизуются в ОЗУ, что ускоряет запись/ чтение.
Взаимодействие между процессами
В ОС UNIX процессы выполняются в собственном адресном пространстве и изолированы друг от друга. Это исключает ( сводит к минимуму) возможные влияния процессов друг на друга, что является необходимым в многозадачных ОС. Т. к. в то же время процессы должны взаимодействовать, то для реализации взаимодействия требуются:
1. Обеспечение средств взаимодействия
2. Исключить нежелательные влияния между ними
Взаимодействие между процессами необходимо для решения следующих задач:
1. Передача данных. Один процесс передает данные другому процессу, при этом объем передаваемых данных должен варьироваться от десятков байтов до нескольких Мбайтов.
2. Совместное использование данных. Вместо копирования данных от одного процесса к другому, они могут совместно использовать одну копию, причем изменения, сделанные одним процессом будут заметны для другого. Количество взаимодействующих процессов может больше двух. При совместном использовании ресурсов процессам может понадобиться протокол взаимодействия для сохранения целостности данных и исключения конфликтов между ними при доступе к данным.
3. Извещения. Процесс может известить другой процесс или группу процессов о наступлении события. Это может понадобиться для синхронизации выполнения нескольких процессов (сигналы, похожие на прерывания).
Задача взаимодействия между процессами решается силами ОС. В UNIX это следующие средства:
1. Сигналы
2. Каналы
3. FIFO – именованные каналы
4. Сообщения (очереди сообщений)
5. Семафоры
6. Разделяемая память
7. Сокеты
1. Сигналы могут уведомлять об ошибках, для синхронизации процессов, для передачи простейших команд от одного процесса к другому, например, для сервера DNS named (1M) таким образом используется сигнал SIGHUP, являющийся сигналом обновления базы данных. Сигналы очень ресурсоемки. Отправка сигнала требует системного вызова, а доставка – прерывания процесса-получателя и операций со стеком ( работа с подпрограммой). Сигналы малоинформативны и их число ограничено.
2. Каналы. На примере команды в командной строке shell рассмотрим синтаксис организации программных каналов:
cat myfile ç wc
Стандартный вывод команды cat(1), которая выводит содержимое файла myfile, передается на стандартный ввод программы wc(1), которая подсчитывает количество строк, слов и символов. В результате получается:
12–
количество строк, слов, символов в myfile
Таким образом, два процесса обменялись данными. При этом использовался программный канал, обеспечивающий однонаправленную передачу данных между двумя задачами.
Для создания канала используется системный вызов pipe(2):
int pipe( int * fildes), иначе int pipe(int filedes[2]);
который возвращает два файловых дискриптора – fildes[0] для записи в канал и fildes[1] для чтения из канала( если неудача, вызов pipe вернет – 1). Теперь один процесс записывает данные в fildes[0], другой может получить эти данные из fildes[1]. Как получает файловый дескриптор fildes[1] другой процесс? При создании процесса наследующие атрибуты дочерний процесс наследует и разделяет все назначенные файловые дескрипторы процесса родительского. Доступ к дескрипторам filedes канала может получить сам процесс, вызвавший pipe(2), и его дочерние процессы. Серьезный недостаток каналов в том, что они могут быть использованы для передачи данных только между родственными процессами и не могут быть использованы для передачи данных между независимыми процессами. В приведенном примере оба процесса cat(1) и wc(1) создаются shell и поэтому являются родственными.
Недостатком каналов является то, что они могут использоваться только для родственных процессов и не могут быть использованы для настоящих серверных программ ( серверы управления сетью и спулеры печати) и не могут существовать постоянно.
3. FIFO
Название каналов FIFO ( First In First Out, 1-м-вошел, 1-м-вышел). FIFO являются однонаправленными средствами передачи данных, причем чтение данных происходит в порядке их записи. FIFO имеют имена, которые позволяют взаимодействовать независимым процессам (именованные каналы).В BSD не используются. FIFO является типом файлов (ls-l покажет в первой позиции p). Для создания FIFO используется системный вызов mknod(2):
int mknod (char *pachname, int mode, int dev),
где pathname – имя файла в Ф. С.( имя FIFO),
mod – флаги владения прав доступа и тд.( поле mode).Например, 0666 –для всех права доступа на запись и чтение.
dev – при создании файла игнорируется.
FIFO может быть создан и из командной строки shell:
$ mkmode name p
После создания FIFO может быть открыт на запись и чтение, причем запись и чтение могут происходить в разных независимых процессах.
Каналы FIFO и обычные каналы работают по следующим правилам:
1. При чтении меньшего числа байтов, чем находятся в канале или FIFO, возвращается требуемое число байтов, остаток сохраняется для последующих чтений.
2. При чтении большего числа байтов, чем есть, возвращается доступное число байтов, а процесс, читающий из канала, должен обработать ситуацию, если прочитано меньше, чем заказано.
3. Если канал пуст и ни один процесс не открыл его на запись, при чтении из канала будет получено 0 байтов. Если канал открывали для записи, но не записали, то вызов read(2) будет заблокирован до появления данных, если в канале не установлен флаг отсутствия блокировки O_NDELAY.
4. Запись числа байтов, меньшего емкости канала или FIFO, гарантировано атомарно. Это означает, что в случае записи в канал одновременно несколькими процессами, порции данных не перемешиваются.
5. При записи большего числа байтов, чем это позволяет канал или FIFO, вызов write(2) блокируется до освобождения места. Атомарность при этом не гарантируется. Если процесс пытается записать данные в канал, не открытый ни одним процессом на чтение, процессу гарантируется сигнал SIGPIPE, а вызов write(2) возвращает 0 с установкой ошибки (errno=EPIPE), если процесс не установил обработки сигнала SIGPIPE, производится обработка по умолчанию – процесс завершается.
Размер канала
В канале может находиться только определенное число байтов, прежде чем следующий вызов write будет заблокирован. Минимальный размер, определенный POSIK равен 512 байтов. Вызов write выполняется для канала неделимыми порциями и запись выполняется ядром за одну непрерывную операцию. Родительский выполняется в бесконечном цикле, а дочерний посылает сообщение родительскому, спрашивая канал и проверяя, поступили ли данные. Системный вызов fcntl устанавливает флаги F_SETFL и O_NONBLOCK
Функции к разделу FIFO
1. Функция pipe(2) (создание канала)
Функция pipe(2) служит для создания однонаправленного (симплексного) канала (анонимного) обмена данными между двумя родственными процессами, т. к. только они имеют возможность получить доступ к одному и тому же каналу. После завершения работы канал уничтожается.
Функция имеет вид:
# include <unistd. h>
int pipe (int fildes[2]);
Функция возвращает два fd в массиве [ ], причем fildes[0] служит для чтения данных из канала, а fildes[1] для записи данных в канал.
2. Функция fcntl(2) ( управление файловыми операциями в уже открытых файлах, заданных дескриптором файла filedes)
# include <fcntl/h> - в этом заголовочном файле определены целочисленные константы: O_RDONLY и O_WRONLY.
int fcntl (int fildes, int cnd,…) – установка и снятие блокировки на файл его часть, создание каналов FIFO.
Функция fcntl(2) выполняет действие cmd с файлом, а третий аргумент зависит от конкретного действия:
а). F_SETLK – установить блокирование записи файла. Структура flock описывает блокирование, и указатель на нее передается в качестве третьего аргумента. При невозможности блокирования fcntl(2) возвращается с ошибкой EACCESS или EAGAIN;
б)F_SETLKW – аналогично предыдущему, но при невозможности блокирования по причине уже существующих блокировок, процесс переходит в состояние сна, ожидая снятие блокировок.
W – ждать;
в). F_SETFL – задает режим записи данных в конец файла.
3. Функция printf – запись в стандартный вывод, форматизованный
4. Системный вызов unlink(2) удаляет файл, например, unlink(²/tmp/usedfile).
Вызов возвращает 0 в случае успешного завершения и – 1 – в случае ошибки.
5. Системный вызов read копирует произвольное число символов или байтов из файла в буфер ( в ASCII)
6. Системный вызов open открывает файл для чтения, записи или создает пустой файл.
7. Системный вызов close – закрывает файл, возвращает файл в случае успешного завершение и – 1 в случае ошибки:
# include <unistd. h>
int close (int filedes)
filedes=open (²file²,O_RDONLY);
.
.
.
close(filedes);
8. Системный вызов write – копирует данные из буфера программы, рассматриваемого как массив, во внешний файл. Как и read, имеет три аргумента: дескриптор файла filedes, указатеь на записываемые данные buffer и n – положительное число записываемых байтов.
# include <unistd. h>
ssize_t write (int filedes, const void *buffer, size_t n);
9. Функция pipe(2) (создание канала)
Функция pipe(2) служит для создания однонаправленного (симплексного) канала (анонимного) обмена данными между двумя родственными процессами, т. к. только они имеют возможность получить доступ к одному и тому же каналу. После завершения работы канал уничтожается.
Функция имеет вид:
# include <unistd. h>
int pipe (int fildes[2]);
Функция возвращает два fd в массиве [ ], причем fildes[0] служит для чтения данных из канала, а fildes[1] для записи данных в канал.
Пример приложения клиент-сервер, использующего FIFO для обмена данными.
Клиент посылает серверу сообщения²Hello², а сервер выводит это сообщение на терминал.
Клиент:
#include <sys/types. h>
#include <fcntl. h>
# include <sys/std. h>
/*Соглашение об имени FIFO*/
# define FIFO ²fifo.1²
main()
{
int writefd, n;
/*Получим доступ к FIFO*/
if ((writefd=open(fIFO, O_WRONLY))<0){
printf(²Невозможно открыть FIFO\n²); exit(1);}
/*Передадим сообщение серверу FIFO*/
if (write(writefd, ²Здравствуй, Мир!\n²,18)!=18){
printf(²Ошибка записи\n²); exit(1);}
/*Закроем FIFO*/
close (writefd);
/*Удалим FIFO*/
if (unlink(FIFO)<0){
printf(²Невозможно удалить FIFO\n²); exit (1); }
exit(0);
}
Сервер:
#include <sys/types. h>
#include <fcntl. h>
#include <sys/stat. h>
#define FIFO ²fifo.1²
#define MAXBUFF
main
main ()
{
int readfd, n;
char buff[MAXBUFF]; /*буфер для чтения данных из FIFO*/
/*Создадим специальный файл FIFO с открытыми для всех правами доступа на чтение и запись*/
if (_mknod(FIFO, S_IFIFO|0666,0)<0){
printf(²Невозможно создать FIFO\n²); exit(1); }
/*Получим доступ к FIFO*/
if ((readfd=open(FIFO, O_RDONLY))<0){
printf(²Невозможно открыть FIFO\n²); exit(1);}
/*Прочитаем сообщение (²Здравствуй, Мир!²) и выведем его на экран*/
while ((n=readfd, buff, MAXBUFF))>0)
if(write (1,buff, n)!=n){
printf(²Ошибка вывода \n²); exit (1); }
/*Закроем FIFO, удаление FIFO – дело клиента*/
close (readfd);
exit(0);
}
Права доступа к объекту
Значение ,,,,, в 8-ричн. | Аналог прав доступа для файлов | Разрешено |
0400 | z | Чтение для владельца |
0200 | - w | Запиь для владельца |
0040 | - - - z | Чтение для вл. группы |
0020 | w | Запись для вл. группы |
0004 | z - - | Чтение для всех ост. |
0002 | w - | Запись для всех ост. |
Идентификаторы и имена в IPC
|
Из за большого объема этот материал размещен на нескольких страницах:
1 2 3 4 5 6 |






