Системно програмиране, М. Филипова 1
IPC механизми на UNIX System VСъобщения
гл. ас. Моника ФилиповаФМИ, Катедра Изчислителни системи
Системно програмиране, М. Филипова 2
Общи свойства Външно име на IPC обект – ключ (цяло число от тип key_t) Вътрешен идентификатор на IPC обект Системна таблица, описваща IPC обектите Структура ipc_perm
struct ipc_perm {key_t key; /* key */ushort uid; /* owner’s user ID */ushort gid; /* owner’s group ID */ushort cuid; /* creator’s user ID */ushort cgid; /* creator’s group ID */ushort mode; /* access mode */ushort seq; /* sequence number */
};
Системно програмиране, М. Филипова 3
Общи свойства
Функции ХХХget Аргумент key – външно име на IPC обект
Създава IPC обект и връща вътрешен идентификатор
Връща вътрешен идентификатор на съществуващ IPC обект Аргумент flag
Флагове – IPC_CREAT и IPC_EXCL
Битове, определящи правата на процеса - mode Функции ХХХctl Реализират управляващи операции над IPC обект Унищожаване
Системно програмиране, М. Филипова 4
IPC механизми на UNIX System V
Съобщения Семафори Обща памет
Заглавен файл <sys/ipc.h>
<sys/msg.h>
<sys/ipc.h>
<sys/sem.h>
<sys/ipc.h>
<sys/shm.h>Създаване/отваряне msgget semget shmget
Управление msgctl semctl shmctl
IPC операции msgsnd, msgrcv semop shmat, shmdt
Системно програмиране, М. Филипова 5
Съобщения
Косвена адресация
Съобщения се предават в и получават от опашка на съобщенията (Message queue, MQ).
Автоматично буфериране
Съществува системен буфер с ограничен капацитет, в който временно могат да се съхраняват изпратени и още неполучени съобщения.
Системно програмиране, М. Филипова 6
Съдържание
Системни структури Създаване и отваряне Изпращане и получаване на съобщения Управляващи операции
Системно програмиране, М. Филипова 7
Системни структури
Queue Heders Data AreaMessage headers
Системно програмиране, М. Филипова 8
Структура msqid_ds
struct msqid_ds {
struct ipc_perm msg_perm;
struct msg *msg_first; /* first message on queue */ struct msg *msg_last; /* last message on queue */ time_t msg_stime; /* time of last msgsnd */
time_t msg_rtime; /* time of last msgrcv */
time_t msg_ctime; /* time of last change */
unsigned long msg_cbytes; /* current number of bytes*/
msgqnum_t msg_qnum; /* number of messages */
msglen_t msg_qbytes; /*max number of bytes on queue*/
pid_t msg_lspid; /* pid of last msgsnd */
pid_t msg_lrpid; /* pid of last msgrcv */
};
Системно програмиране, М. Филипова 9
Създаване и отваряне
#include <sys/ipc.h>
#include <sys/msg.h>
int msgget(key_t key, int flag); Аргумент key – външно име на MQ или IPC_PRIVATE
Създава нова MQ за key ако е истина едно от:
– key е IPC_PRIVATE
– за key няма MQ и е вдигнат флаг IPC_CREAT
Отваря съществуваща MQ
Връща идентификатор на MQ при успех, -1 при грешка.
Системно програмиране, М. Филипова 10
Изпращане и получаване на съобщения
Структура на съобщениеstruct msgbuf {
long mtype; /* type of message */
char mtext[1]; /* message text */
};
#include <sys/ipc.h>
#include <sys/msg.h>
int msgsnd(int msgid, struct msgbuf *msg,
size_t size, int flag);
Аргумент flag – IPC_NOWAIT
Връща 0 при успех, -1 при грешка.
Системно програмиране, М. Филипова 11
Изпращане и получаване на съобщения
#include <sys/ipc.h>
#include <sys/msg.h>
int msgrcv(int msgid, struct msgbuf *msg,
size_t size, long type, int flag);
Аргумент type
=0 – първото съобщение в MQ
>0 – първото съобщение в MQ от тип type
<0 – първото съобщение в MQ от тип най-малкото число <=|type|
Аргумент flag – IPC_NOWAIT, MSG_NOERROR
Връща дължина на съобщението при успех, -1 при грешка.
Системно програмиране, М. Филипова 12
Управляващи операции#include <sys/ipc.h>
#include <sys/msg.h>
int msgctl(int msgid, int cmd,
struct msqid_ds *buf); Аргумент cmd
IPC_RMID – унищожава MQ
IPC_STAT – връща информация за MQ чрез buf
IPC_SET – изменя атрибути на MQ чрез buf: msg_perm.uid, msg_perm.gid, msg_perm.mode,
msg_qbytes
Връща 0 при успех, -1 при грешка.
Системно програмиране, М. Филипова 13
Пример. Създаване на опашка на съобщения, извеждане на информация за нея и унищожаване#include <sys/ipc.h>#include <sys/msg.h>#include "ourhdr.h"
struct msgb { int mtype; char mtext[1];};
main(void){int msgid;struct msgb msg;struct msqid_ds info;
if ( (msgid = msgget(IPC_PRIVATE, 0600)) == -1) err_sys_exit("Msgget error"); msg.mtype = 1; msg.mtext[0] = 'a'; msgsnd(msgid, &msg, 1, 0);
Системно програмиране, М. Филипова 14
if (msgctl(msgid, IPC_STAT, &info) == -1 ) err_sys_exit("Msgctl IPC_STAT error");
printf("MQ: %03o, cbytes=%lu, qnum=%lu, qbytes=%lu\n",
info.msg_perm.mode&0777, info.msg_cbytes,
info.msg_qnum, info.msg_qbytes);
system("ipcs -q"); if (msgctl(msgid, IPC_RMID, 0) == -1 ) err_sys_exit("Msgctl IPC_RMID error");
printf("MQ destroyed\n"); exit(0);}
Системно програмиране, М. Филипова 15
Резултат от изпълнение на програмата$ a.out # in Linux 2.0MQ: 600, cbytes=1, qnum=1, qbytes=16384
------ Message Queues --------msqid owner perms used-bytes messages128 moni 600 1 1
MQ destroyed
$ a.out # in Linux 2.6MQ: 600, cbytes=1, qnum=1, qbytes=65536
------ Message Queues --------key msqid owner perms used-bytes messages0x00000000 32768 moni 600 1 1
MQ destroyed