#include <sys/types.h> #include <sys/ipc.h> #include <sys/msg.h> #define MSGKEY 75 struct msgform { long mtype; char mtext[256]; }msg; int msgid; main() { int i,pid,*pint; extern cleanup(); for (i = 0; i < 20; i++) signal(i,cleanup); msgid = msgget(MSGKEY,0777IPC_CREAT); for (;;) { msgrcv(msgid,&msg,256,1,0); pint = (int *) msg.mtext; pid = *pint; printf("сервер: получил от процесса с pid %d\n", pid); msg.mtype = pid; *pint = getpid(); msgsnd(msgid,&msg,sizeof(int),0); } } cleanup() { msgctl(msgid,IPC_RMID,0); exit(); } |
Сообщения имеют форму "тип - текст", где текст представляет собой поток байтов. Указание типа дает процессам возможность выбирать сообщения только определенного рода, что в файловой системе не так легко сделать. Таким образом, процессы могут выбирать из очереди сообщения определенного типа в порядке их поступления, причем эта очередность гарантируется ядром. Несмотря на то, что обмен сообщениями может быть реализован на пользовательском уровне средствами файловой системы, представленный вашему вниманию механизм обеспечивает более эффективную организацию передачи данных между процессами.
С помощью системной функции msgctl процесс может запросить информацию о статусе дескриптора сообщения, установить этот статус или удалить дескриптор сообщения из системы. Синтаксис вызова функции:
msgctl(id,cmd,mstatbuf)где id - дескриптор сообщения, cmd - тип команды, mstatbuf - адрес пользовательской структуры, в которой будут храниться управляющие параметры или результаты обработки запроса. Более подробно об аргументах функции пойдет речь в Приложении.
Вернемся к примеру, представленному на Рисунке 11.8. Обслуживающий процесс принимает сигналы и с помощью функции cleanup удаляет очередь сообщений из системы. Если же им не было поймано ни одного сигнала или был получен сигнал SIGKILL, очередь сообщений остается в системе, даже если на нее не ссылается ни один из процессов. Дальнейшие попытки исключительно создания новой очереди сообщений с данным ключом (идентификатором) не будут иметь успех до тех пор, пока старая очередь не будет удалена из системы.