Программирование >>  Структура ядра и системные вызовы 

1 ... 47 48 49 [ 50 ] 51 52 53 ... 98


EEXl ST В аргументе flag установлены флаги IPC EXCL и Ii C CREAT,

а очередь с указанным значением key уже есть

EACCESS Очередь с указанным значением key существует, но у вызы-j

вающего процесса нет прав доступа к ней

10.3.4. Функция msgsnd

Прототип функции msgsnd выглядит следующим образом:

#include <sys/types.h> #include <sys/ipc.h> #include <sys/msg.h>

int msgsnd (int msgfd, const void* msgPtr, int len, int flag );

Этот API передает сообщение (на которое указывает msgPtr) в очередь, обозначенную дескриптором msgfd.

Значение msgfd определяется возвращаемым значением функции msgget.

Фактическое значение аргумента msgPtr - указатель на объект, который содержит реальный текст и тип сообщения, подлежащего передаче. Для объявления объекта в этом случае можно использовать следующий тип данных:

struct msgbuf {

long mtype;

char mtext[MSGMAX];

тип сообщения буфер для текста сообщения

Значение аргумента len - это размер (в байтах), поля mtext объекта, на который указывает аргумент msgPtr

Аргумент flag может иметь значение 0. Это означает, что при необходимости процесс можно блокировать до тех пор, пока данная функция не будет успешно выполнена. Если этот аргумент имеет значение IPCNOWAIT, то при блокировании процесса выполнение функции прерывается.

В случае успешного выполнения этот API возвращает О, а в случае неудачи -1.

Ниже приведена программа test msgsnd. С, которая создает новую очередь сообщений с ключевым идентификатором 100 и устанавливает следующие права доступа к очереди: чтение и запись для владельца, только чтение для членов группы, только запись для прочих пользователей. Если вызов msgget выполнен успешно, процесс передает в эту очередь сообщение Hello, тип которого - 15, и указывает, что данный вызов - неблокирующий. Если msgget или msgsnd дают сбой, процесс вызывает функцию perror, которая выводит на экран диагностртческое сообщение.

yfinclude <stdio.h>

finclude <string.h>

kinclude <sys/ipc.h>

#Vnclude <sys/msg.h>

#i]fndef MSGMAX

#define MSGMAX 1102

#endif ,

struct mbuf

long mtype; char mtext[MSGMAX]; } mobj = { 15, Hello },

int mainO {

int fd = msgget (100, IPC CREATIPC EXCL0642);

if (fd==-l M msgsnd(fd,&mpbj,strlen(mobj.mtext)+1, IPC NOWAIT))

perror( message );

return 0;

10.3.5. Функция msgrcv

Прототип функции msgrcv выглядит так:

#include <sys/types.h> #include <sys/ipc.h> #include <sys/msg.h>

int msgsnd (int msgfd, const void* msgPtr, int len, int mtype, int flag );

Этот API принимает сообщение типа mtype из очереди сообщений, обозначенной дескриптором msgfd. Полученное сообщение хранится в объекте, на который указывает аргумент msgPtr. Значение аргумента len - это Максимальный размер (в байтах) текста сообщения, которое может быть принято данным вызовом.

Значение msd берется из вызова функции msgget.

Фактическое значение аргумента msgPtr - указатель на объект, имеющий структуру данных, похожую на struct msgbuf.

Значение mtype - это тип сообщения, подлежащего приему. Ниже перечислены возможные значения данного аргумента и их смысл.



Положительное целое Отрицательное целое

Принять из очереди самое старое сообщение любог типа

Принять самое старое сообщение указанного типа

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

Аргумент flag может иметь значение 0. Это означает, что процесс можно блокировать, если ни одно сообщение в очереди не удовлетворяет критериям выбора, заданным аргументом mtype. Если в очереди есть сообщение, которое удовлетворяет этим критериям, но превышает величину len, то функция возвращает код неудачного заверщения.

Если процесс указал в аргументе flag значение IPC NOWAIT, то вызов будет неблокирующим. Кроме того, если в названном аргументе установлен флаг MSG NOERROR, то сообщение, находящееся в очереди, можно читать (даже если его размер превышает len байтов). Функция возвращает вызывающему процессу первые len байтов текста сообщения, а остальные данные отбрасывает.

Функция msgrcv возвращает количество байтов, записанных в буфер mtext объекта, на который указывает аргумент msgPtr, или -1 (в случае неудачи).

Приведенная ниже программа testjnsgrcv.C подобна программе, рассмотренной в предыдущем разделе, но после передачи сообщения в очередь процесс вызывает API msgrcv, который ждет и выбирает из очереди сообщение типа 20. Если вызов выполняется успешно, процесс направляет выбранное сообщение на стандартное устройство вывода; в противном случае он вызывает функцию perror, которая выводит на экран диагностическое сообщение.

♦include <iostream.h> ♦include <stdio.h> ♦include <string.h> ♦include <sys/stat.h> ♦include <SYs/ipc.h> ♦include <sYs/msg.h>

♦ifndef MSGMAX ♦define MSGMAX ♦endif

1024

/* структура данных сообщения */

struct mbuf

long mtype; char mtext[MSGMAX); ) mobj = ( 15, Hello );

10.3.6. функция msgcti

Прототип функции msgcti имеет следующий вид:

#include <sys/types.h> #include <sys/lpc.h> #lnclude <sys/msg.h>

int msgsnd (int msgfd, int cmd struct msqid ds* mbufPtr );

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

Значение аргумента msgfd берется из вызова функции msgget.

Ниже перечислены возможные значения аргумента cmd и их смысл.

Значение cmd Смысл

IPC STAT IPC SET

IPC RMID

Копировать управляющие параметры очереди в объект, указанный аргументом mbufPtr

Заменить управляющие параметры очереди параметрами, содержащимися в объекте, на который >казывает аргумент mbufPtr. Чтобы выполнить эту операцию, вызьшаюший процесс должен иметь права либо привилегированного пользователя, либо создателя или назначенного владельца очереди. С помощью этого API можно устанавливать UID владельца очереди и идентификатор его группы, права доступа и (или) уменьшать лимит msgqbyte очереди

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

В случае успешного вьшолнения этот API юзвращает О, в случае неудачи - -1. Приведенная ниже программа testjnsgctl. С открывает очередь сообще-ии с ключевым идентификатором 100 и вызывает функцию msgcti для

int perm - S IRUSRS IWUSRS IRGRPS IWOTH; int fd = msgget (100, IPC CREATIPC EXCLperm);

if (fd==-l II msgsnd(fd,smobj,strlen(mobj.mtext)+1, IPC NOWAIT)) \ perror( message );

else if (msgrcv(fd,smobj, MSGMAX,0, IPC NOWAITMSG NOERROR)0)

cout mobj.mtext endl; else perror( msgrcv ); return 0;



считывания управляющих параметров очереди. Если вызовы msgget и msgctlf выполняются успешно, процесс выводит на экран количество сообщение находящихся в очереди на данный момент времени. Еще одним вызово1( msgctl процесс устанавливает идентификатор владельца очереди равнь/м своему идентификатору. Наконец, вызвав msgctlb третий раз, процесс удаляет очередь. j

tinclude <iostream.h>

finclude <stdio.h> tinclude <unistd.h> tinclude <sys/ipc.h> finclude <sys/msg.h> int main()

struct msqid ds mbuf;

int fd = msgget (100, 0);

if (fdO && msgctl(fd,IPC STAT,&mbuf)) {

cout fmsg in queue: << mbuf.msg qnum endl;

mbuf.msg perm.uid = getuidO; изменить UID владельца

if (msgctl(fd,IPC SET,&mbuf)==-l) perror( msgctl );

) else

perror( msgctl ); if (msgctl(fd,IPC RMID,0)) perror( msgctl - IPC RMID ); return 0;

10.3.7. Пример приложения клиент/сервер

в этом разделе описывается приложение клиент/сервер, в котором используются сообщения. Первая программа, server. С, создает серверный процесс-демон, который непрерывно работает в фоновом режиме, предоставляя услуги клиентским процессам. Клиентские процессы создаются программой client.С. Они отправляют процессу-демону запросы на обслуживание, передавая сообщения в очередь, которой владеет и управляет этот демон. Демон отвечает клиентам, передавая сообщения в эту же очередь.

В частности, каждое сообщение-запрос на обслуживание, передаваемое клиентским процессом серверу-демону, должно иметь следующие поля:

Поле данных сообщения Содержание

message type (тип сообщения)

message text (текст сообщения)

Целое число, определяющее, какой командой осуществляется запрос на обслуживание

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

Команда запроса Предоставляемая услуга на обслуживание

4-99

Посылает клиенту значения местного времени и даты Сообщает клиенту текущее время в универсальном формата

Удаляет очередь сообщений и завершает процесс-демон Ответ клиенту не посылается

Посылает клиенту сообщение об ошибке

Каждое ответное сообщение, посьшаемое сервером клиенту, содержит следующие поля:

Поле данных сообщения Содержание

message type (тип сообщения)

message text (текст сообщения)

Идентификатор клиентского процесса Данные ответа сервера в виде строки символов

Поскольку сервер и клиент взаимодействуют между собой через общую очередь сообщений, то можно определить класс message, инкапсулирующий все API, предназначенные для обмена сообщениями. Этот класс определяется в следующем заголовке message.h, который используется обеими программами, server. С и client. С:

tifndef MESSAGE H fdefine MESSAGE H ♦include <stdio.h> finclude <stdlib.h> ♦include <memory.h> finclude <unistd.h> ♦include <sys/ipc.h> finclude <sys/msg.h> ♦include <sys/wait.h>

/* общие объявления для серверного процесса */

enum 1 MSGKEY= 176, MAX LEN =256, ILLEGAL CMD = 4 );

enum ( LOCAL TIME = 1, UTC TIME =2, QUIT CMD =3);

typedef struct mgbuf {

long mtype; char mtext[MAX LEN3; 1 MSGBUF;

class message

private:



1 ... 47 48 49 [ 50 ] 51 52 53 ... 98

© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки.
Яндекс.Метрика