русс | укр

Языки программирования

ПаскальСиАссемблерJavaMatlabPhpHtmlJavaScriptCSSC#DelphiТурбо Пролог

Компьютерные сетиСистемное программное обеспечениеИнформационные технологииПрограммирование

Все о программировании


Linux Unix Алгоритмические языки Аналоговые и гибридные вычислительные устройства Архитектура микроконтроллеров Введение в разработку распределенных информационных систем Введение в численные методы Дискретная математика Информационное обслуживание пользователей Информация и моделирование в управлении производством Компьютерная графика Математическое и компьютерное моделирование Моделирование Нейрокомпьютеры Проектирование программ диагностики компьютерных систем и сетей Проектирование системных программ Системы счисления Теория статистики Теория оптимизации Уроки AutoCAD 3D Уроки базы данных Access Уроки Orcad Цифровые автоматы Шпаргалки по компьютеру Шпаргалки по программированию Экспертные системы Элементы теории информации

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


Дата добавления: 2014-11-28; просмотров: 1375; Нарушение авторских прав


Очереди сообщений поддерживаются ядром UNIX.

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

В области ядра имеется таблица очереди сообщений. Каждая запись таблицы очередей характеризует конкретную очередь сообщений и содержит следующую информацию:

  • Имя очереди – целочисленный идентификатор. Присваивается процессом, который создаёт очередь. Другие процессы, используя этот ключ, могут открывать очередь и получать к ней доступ.
  • Идентификатор владельца (UID) и идентификатор группы (GID).
  • UID и GID владельца очереди.
  • Права доступа к очереди.
  • Время и идентификатор процесса, который последним передал сообщение в очередь.
  • Время и идентификатор процесса получившего последним сообщение из очереди.
  • Указатель на связный список записей сообщений, находящихся в очереди.

Каждая запись в очереди сообщений содержит:

    1. Тип сообщения.
    2. Число байт данных.
    3. Указатель на область данных ядра, где находятся сами сообщения.

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

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

Процесс может выбрать сообщение из очереди следующим образом:

· самое старое.

· указанного типа.

· числовое значение которого наименьшее из меньших или равных значению типа, указанного процессом.

 

FTOK

ftok - преобразовывает имя файла и идентификатор проекта в ключ для системных вызовов

 

СИНТАКСИС

# include <sys/types.h>

# include <sys/ipc.h>

key_t ftok(const char *pathname, int proj_id);



 

ОПИСАНИЕ

Функция ftok использует файл с именем pathname (которое должно указывать на существующий файл к которому есть доступ) и младшие 8 бит proj_id (который должен быть отличен от нуля) для создания ключа с типом key_t, используемого в System V IPC для работы с msgget(), semget(), и shmget().

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

 

ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ

В случае удачного завершения вызова возвращается значение созданного ключа key_t. При ошибке возвращается -1, а в переменную errno записывается код ошибки согласно системному вызову stat().

 

MSGCTL

msgctl - выполняет контрольные операции над сообщениями

 

СИНТАКСИС

#include <sys/types.h>

#include <sys/ipc.h>

#include <sys/msg.h>

int msgctl(int msqid, int cmd, struct msqid_ds *buf);

 

ОПИСАНИЕ

Эта функция выполняет контрольную операцию, заданную в cmd, над очередью сообщений msqid. Возможные значения cmd:

 

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

IPC_SET - Записать значения некоторых элементов структуры msqid_ds , адрес которой указан в buf, в структуру данных из очереди сообщений, обновляя при этом его поле msg_ctime. Предполагаемые элементы заданной пользователем структуры struct msqid_ds, адрес которой указан в buf, являются следующими:

msg_perm.uid

msg_perm.gid

msg_perm.mode /* только неосновные 9 битов */

msg_qbytes

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

IPC_RMID - Немедленно удалить очередь сообщений и структуры его данных, "разбудив" все процессы, ожидающие записи или чтения этой очереди (при этом функция возвращает ошибку, а переменная errno приобретает значение EIDRM). Эффективный идентификатор пользователя процесса, вызывающего эту функцию, должен принадлежать либо root, либо создателю или владельцу очереди сообщений.

 

ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ

При удачном завершении вызова возвращаемое значение равно нулю. При ошибке возвращается -1, а переменной errno присваивается номер ошибки.

 

MSGGET

msgget - получает идентификатор очереди сообщений

 

СИНТАКСИС

#include <sys/types.h>

#include <sys/ipc.h>

#include <sys/msg.h>

int msgget(key_t key, int msgflg);

 

ОПИСАНИЕ

Эта функция возвращает идентификатор очереди сообщений, связанный со значением параметра key . Она также создает новую очередь сообщений, если key равен IPC_PRIVATE ; в случае если key не равен IPC_PRIVATE,то с параметром key не сопоставлена ни одна существующая очередь сообщений и в поле msgflg включен флаг IPC_CREAT . (т.е., значение msgflg&IPC_CREAT не равно нулю). Поля IPC_CREAT и IPC_EXCL в msgflg играют ту же роль для очередей сообщений, что и O_CREAT и O_EXCL в параметре mode системной функции open(): функция msgget вернет ошибку, если в msgflg включены оба флага: IPC_CREAT и IPC_EXCL ,- а такая очередь сообщений для key уже существует.

При создании очереди вспомогательные 9 битов параметра msgflg определяют права доступа к очереди сообщений. Эти биты прав имеют тот же формат и значение, что и параметр прав доступа для системных функций open() или creat(). (Права на исполнение не используются.)

Более того, при создании очереди этот системный вызов инициализирует системную структуру данных в очереди сообщений msqid_ds следующим образом:

  • msg_perm.cuid и msg_perm.uid устанавливаются для эффективного идентификатора пользователя, запускающего вызывающий процесс.
  • msg_perm.cgid и msg_perm.gid устанавливаются для эффективного идентификатора группы вызывающего процесса.
  • Вспомогательные 9 битов msg_perm.mode приравниваются к вспомогательным 9-и битам msgflg.
  • Значение msg_qnum, msg_lspid, msg_lrpid, msg_stime и msg_rtime равно нулю.
  • msg_ctime устанавливается согласно текущему времени.
  • msg_qbytes устанавливается согласно системному лимиту, заданному MSGMNB.

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

 

ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ

При удачном завершении вызова возвращаемое значение равно нулю. При ошибке возвращается -1, а переменной errno присваивается номер ошибки.

MSGOP

msgop - работает с сообщениями

 

СИНТАКСИС

#include <sys/types.h>

#include <sys/ipc.h>

#include <sys/msg.h>

int msgsnd(int msqid, struct msgbuf *msgp, size_t msgsz, int msgflg);

ssize_t msgrcv(int msqid, struct msgbuf *msgp, size_t msgsz, long msgtyp, int msgflg);

 

ОПИСАНИЕ

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

struct msgbu {

long mtype;/* тип сообщения должен быть > 0 */

char mtext[1];/* содержимое сообщения */

};,

а размер массива mtext равен неотрицательному целому числу msgsz. Поле mtype должно быть обозначено как положительное целое число, используемое процессом-получателем для выбора сообщений.

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

Системный вызов msgsnd помещает сообщение, указанное параметром msgp, в очередь сообщений, идентификатор которой указывается в параметре msqid.

Параметр msgflg определяет поведение системы при помещении в очередь сообщения, размер которого больше msg_qbytes. При значении IPC_NOWAIT сообщение не будет послано, а системный вызов возвратит ошибку, записав в переменную errno значение EAGAIN. В противном случае работа процесса приостанавливается до тех пор, пока причина остановки не будет устранена (в этом случае сообщение будет послано, и системный вызов будет выполнен успешно), или очередь сообщений не будет удалена (в этом случае системный вызов вернет ошибку, установив значение errno равным EIDRM), или процесс не получит сигнал, который должен быть обработан (системный вызов вернет ошибку, установив значение errno равным EINTR).

При удачном завершении операции структура данных очереди сообщений будет обновлена следующим образом: значение

  • msg_lspid будет установлено равным идентификатору вызывающего процесса. Значение
  • msg_qnum будет увеличено на 1. Значение
  • msg_stime будет установлено равным текущему времени.

Системный вызов msgrcv записывает сообщение из очереди (идентификатор которой указан в msqid) в буфер msgbuf (находящийся в msgp), удаляя сообщение при удачном завершении операции.

Параметр msgsz задает максимальный размер элемента mtext структуры, находящейся по адресу, указанному в аргументе msgp. Если длина текста сообщения больше, чем msgsz, и флаг msgflg установлен в MSG_NOERROR, то текст сообщения будет урезан (а урезанная часть потеряна), иначе сообщение не удаляется из очереди, а системный вызов возвращает ошибку, установив значение errno , равное E2BIG.

Параметр msgtyp задает тип сообщения следующим образом:

  • если msgtyp равен нулю, то используется первое сообщение из очереди;
  • если msgtyp больше нуля, то из очереди берется первое сообщение типа msgtyp (если только во флаге msgflg нет бита MSG_EXCEPT. В этом случае из очереди берется первое сообщение, тип которого не равен msgtyp).
  • Если msgtyp меньше нуля, то из очереди берется первое сообщение со значением, меньшим, чем абсолютное значение msgtyp.

Параметр msgflg состоит из комбинации следующих флагов:

  1. IPC_NOWAIT , который указывает на немедленный возврат из функции, если в очереди нет сообщений необходимого типа. При этом системный вызов возвращает ошибку, устанавливая значение errno равным ENOMSG;
  2. MSG_EXCEPT , который используется (если msgtyp больше, чем 0) для чтения первого сообщения, тип которого не равен msgtyp;
  3. MSG_NOERROR , используемый для урезания текста сообщения, размер которого больше msgsz байтов.

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

    • сообщение необходимого типа помещено в очередь;
    • очередь сообщений удалена из системы (в этом случае системный вызов возвращает ошибку, устанавливая значение errno , равное EIDRM).
    • Вызывающий процесс получает сигнал, который он должен обработать. В этом случае системный вызов возвращает ошибку, устанавливая значение переменной errno , равное EINTR.

При удачном завершении операции структура данных очереди сообщений будет обновлена следующим образом: значение

msg_lrpid будет обозначать идентификатор вызывающего процесса;

msg_qnum уменьшается на 1; значение

msg_rtime будет равно значению текущего времени.

 

ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ

При ошибке обе функции возвращают -1, а переменная errno приобретает соответствующее значение. В противном случае msgsnd возвращает 0, а msgrvc возвращает количество байтов, скопированных в массив mtext.

 

Пример программы

Программа client читает данные (числа) из файла и посылает их как сообщение программе server. Программа server читает данные из сообщения, суммирует их и записывает результат в файл. Внимание! Для получения ключа необходимо создать файл с именем “server” в каталоге программы.

 

Файл server.c

 

#include <stdio.h>

#include <fcntl.h>

#include <sys/types.h>

#include <sys/ipc.h>

#include <sys/msg.h>

#include "mesg.h" //описание структуры сообщения

 

#define PERM 0666 //права доступа к сообщению

 

FILE *fd; //дескриптор файла результатов

Message m; //структура сообщения

key_t key; //ключ сообщения

float sum; //сумма чисел

int msgid; //идентификатор сообщения

int n; //количесво прочитанных байт

 

int main(void)

{

printf("\n\t.:SERVER:.\n");

m.mtype=1L; //определяем тип сообщения

if ((key=ftok("server",'A'))<0) //получаем ключ сообщения

{perror("\n\tError (server - ftok)\n");return 0;}

printf("\n\tGet a key\n");

if((msgid=msgget(key,PERM|IPC_CREAT))<0) //получаем дескриптор сообщения

{perror("\n\tError (server - msgget)\n");return 0;}

printf("\tCreate a message\n");

if ((fd=fopen("result.txt","w+"))==NULL) //создаём файл результатов

{perror("\n\tError (server - fopen)\n");return 0;}

printf("\tOpen(Create) result file\n");

while ((n=msgrcv(msgid,&m,sizeof(m),m.mtype,0))>0) //получаем сообщение

{

sum=m.cord[0]+m.cord[1]+m.cord[2]+m.cord[3]+m.cord[4]+m.cord[5];//суммируем

printf("\tSum=%f\n",sum); //выводим сумму чисел на экран

if ((fprintf(fd,"Sum=%f \n",sum))<=0) //и записываем её в файл

{perror("\n\tError (server - fprintf)\n");return 0;}

printf("\tResult has writen to file\n");

}

close(fd); //закрываем дескриптор файла результатов

return 0;

}

 

Файл client.c

 

#include <stdio.h>

#include <fcntl.h>

#include <sys/types.h>

#include <sys/ipc.h>

#include <sys/msg.h>

#include "mesg.h" //описание структуры сообщения

 

FILE *fd; //дескриптор файла данных

Message m; //структура сообщения

key_t key; //ключ сообщения

int msgid; //идентификатор сообщения

 

int main(void)

{

printf("\n\t.:CLIENT:.\n");

m.mtype=1L; //определяем тип сообщения

if ((key=ftok("server",'A'))<0) //получаем ключ сооющения

{perror("\n\tError (client - ftok)\n");return 0;}

printf("\n\tGet a key\n");

if((msgid=msgget(key,0))<0) //получаем дескриптор сообщения

{perror("\n\tError (client - msgget)\n");return 0;}

printf("\tGet access to messages\n");

if ((fd=fopen("data.txt","r+"))==NULL) //открываем файл данных для чтения

{perror("\n\tError (client - fopen)\n");return 0;}

printf("\tOpen data file\n");

while ((fscanf(fd,"%f %f %f %f %f %f ",&m.cord[0],&m.cord[1],

&m.cord[2],&m.cord[3],&m.cord[4],&m.cord[5]))!=EOF)

{ //читаем из файла 6 чисел

printf("\n\tContent of data file:\n"); //выводим их на экран

printf("\n\t%f %f %f %f %f %f\n",m.cord[0],m.cord[1],

m.cord[2],m.cord[3],m.cord[4],m.cord[5]);

if ((msgsnd(msgid,(void*)&m,sizeof(m.cord),0))!=0) //посылаем сообщение

{perror("\n\tError (client - msgsnd)\n");return 0;}

printf("\tMessage is sent\n");

}

if(msgctl(msgid,IPC_RMID,0)<0) //удаляем дескриптор сообщения

{perror("\n\tError (client - msgctl\n");return 0;}

printf("\tMessage ID has deleted\n");

close(fd); //закрываем дескриптор файла данных

return 0;

}

 

Файл mesg.h

 

//файл содержит объявление структуры сообщения

typedef struct our_msgbuf //имя структуры

{

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

float cord[6]; //массив из шести вещественных чисел

}Message; //тип структуры

 

 



<== предыдущая лекция | следующая лекция ==>
Сегменты разделяемой памяти | Семафоры


Карта сайта Карта сайта укр


Уроки php mysql Программирование

Онлайн система счисления Калькулятор онлайн обычный Инженерный калькулятор онлайн Замена русских букв на английские для вебмастеров Замена русских букв на английские

Аппаратное и программное обеспечение Графика и компьютерная сфера Интегрированная геоинформационная система Интернет Компьютер Комплектующие компьютера Лекции Методы и средства измерений неэлектрических величин Обслуживание компьютерных и периферийных устройств Операционные системы Параллельное программирование Проектирование электронных средств Периферийные устройства Полезные ресурсы для программистов Программы для программистов Статьи для программистов Cтруктура и организация данных


 


Не нашли то, что искали? Google вам в помощь!

 
 

© life-prog.ru При использовании материалов прямая ссылка на сайт обязательна.

Генерация страницы за: 0.011 сек.