Главная страница  Взаимодействие нетривиальных процессов 

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 [ 46 ] 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186

msqid ds{}

I msqid ->

lpc perm{}

msgjirst -

msgjast

msg ctime

next

type = 100

length = 1

data

next

type = 200

length = 2

data

NULL

type = 300

length = 3

data

ядро

Рис. 6.1. Структура очереди System V в ядре

6.2. Функция msgget

Создать новую очередь сообщений или получить доступ к существующей можно с помощью функции msgget:

finclude <sys/msg.h>

int msgget(key t key. int oflag):

I* Возвращает неотрицательный идентификатор в случае успешного завершения. -1 в случае ошибки */

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

Флаг oflag представляет собой комбинацию разрешений чтения-записи, показанную в табл. 3.3. К разрешениям можно добавить флаги I PC CREAT или I PC CREAT IPC EXCL с помощью логического сложения, как уже говорилось в связи с рис. 3.2.

При создании новой очереди сообщений инициализируются следующие поля структуры msqi d ds:

ш полям uid и cuid структуры msg perm присваивается значение действующего идентификатора пользователя вызвавшего процесса, а полям gi d и cgi d - действующего идентификатора группы;

* разрешения чтения-записи, указанные в of 1 ag, помещаются в msg perm.mode;

И значения msg qnuii, msg l spi d, msg l rpi d, msg sti me и msg rti me устанавливаются в 0;

Ш в msg ctime записывается текущее время;

в msg qbytes помещается системное ограничение на размер очереди.

6.3. функция msgsnd

После открытия очереди сообщений с помощью функции msgget можно помещать сообщения в эту очередь с помощью msgsnd. finclude <sys/msg.h>

int msgsndCint msqid. const void *ptr. size t lengtli. int flag):



/* Возвращает О в случае успешного завершения: -1 - в случае ошибки */

Здесь msqid представляет собой идентификатор очереди, возвращаемый msgget. Указательргуказывает на структуру следующего шаблона, определенного в <sys/ msg.h>:

struct msgbuf {

long mtype: /* тип сообщения, должен быть > О */ char mtextEl]; /* данные */

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

Название mtext в структуре msgbuf употреблено не вполне правильно; данные в сообщении совсем не обязательно должны быть текстом. Разрешена передача любых типов данных как в двоичном, так и в текстовом формате. Ядро никак не интерпретирует содержимое сообщения.

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

Например, если приложению нужно передавать сообщения, состоящие из 16-разрядного целого, за которым следует 8-байтовый массив символов, оно может определить свою собственную структуру так:

#clefine MYJATA 8 typedef struct niy nisgbuf {

long mtype: /* тип сообщения */

intl6 t mshort: /* начало данных */

char mchar[MY DATA]: } Message:

Аргумент /engtA функции msgsnd указывает длину сообщения в байтах. Это длина пользовательских данных, следующих за типом сообщения (целое типа long). Длина может быть и 0. В указанном выше примере длина может быть вычислена как sizeof (Message) - sizeof(long).

Аргумент flag может быть либо О, либо IPC NOWAIT. В последнем случае он отключает блокировку для msgsnd: если для нового сообщения недостаточно места в очереди, возврат из функции происходит немедленно. Это может произойти, если:

Я в данной очереди уже имеется слишком много данных (значение msg qbytes в структуре msqid ds);



Ж во всей системе имеется слишком много сообщений.

Если верно одно из этих условий и установлен флаг I PC NOWAIT, функция msgsnd возвращает ошибку с кодом EAGAIN. Если флаг I PC NOWAIT не указан, а одно из этих условий выполняется, поток приостанавливается до тех пор, пока не произойдет одно из следующего:

Ш для сообщения освободится достаточно места;

i? очередь с идентификатором msqid будет удалена из системы (в этом случае возвращается ошибка с кодом EIDRM);

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

6.4. Функция msgrcv

Сообщение может быть считано из очереди с помощью функции msgrcv. finclude <sys/nisg.h>

ssize t msgrcvCint msqid. void *ptr. size t length, long type, int flag): I* Возвращает количество данных в сообщении, -1 - в случае ошибки */

Аргумент ptr 5псазывает, куда следует помещать принимаемые данные. Как и для msgsnd, он указывает на поле данных типа long (рис. 4.13), которое непосредственно предшествует полезным данным.

Аргумент length задает размер относящейся к полезным данным части буфера, на который указывает ptr. Это максимальное количество данных, которое может быть возвращено функцией. Поле типа 1 ong не входит в эту длину.

Аргумент type определяет тип сообщения, которое нужно считать из очереди:

ii если значение type равно О, возвращается первое сообщение в очереди (то есть при указании типа О возвращается старейшее сообщение);

ii если тип больше О, возвращается первое сообщение, тип которого равен указанному;

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

Рассмотрим пример очереди сообщений, изображенный на рис, 6.1. В этой очереди имеются три сообщения:

Ш первое сообщение имеет тип 100 и длину 1;

Ш второе сообщение имеет тип 200 и длину 2;

Ш третье сообщение имеет тип 300 и длину 3.

Таблица 6.1 показывает, какое сообщение будет возвращено при различных значениях аргумента type.

Таблица 6.1. Возвращаемое сообщение в зависимости от аргумента type

type Тип возвращаемого сообщения

О 100

100 100

200 200

-продолжение



1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 [ 46 ] 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186

© 2000 - 2024 ULTRASONEX-AMFODENT.RU.
Копирование материалов разрешено исключительно при условии цититирования.