Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
IPC.doc
Скачиваний:
0
Добавлен:
01.05.2025
Размер:
536.06 Кб
Скачать

Обмен составными сообщениями

Функции:

SETIOV(iov, addr, len);

MsgSendv (int coid, const siov, int sparts, const riov, int rparts);

MsgReceivev (int chid, const riov, int rparts, struct _msg_info *info );

Функция SETIOV() содержит два элемента — адрес и длину.

Функции MsgSendv () и MsgReceivev () имеют почти те же самые аргументы, что и функции MsgSend() и MsgReceive(), рассмотренные ранее.

Аргументы:

  • sparts и rparts указывают число передаваемых и принимаемых частей;

  • siov и riov указывают на адреса заголовков передаваемого и принимаемого сообщений.

Замечания:

•Число фрагментов ограничено значением 231.

•Ядро просто копирует данные, указанные вектором IOV, из одного адресного пространства в другое.

•Вектор-источник и вектор-приемник не должны совпадать.

Для передачи составного сообщения серверу клиент должен сделать так:

// Настроить структуру IOV для передачи:

SETIOV (iov +0, header, 12);

SETIOV (iov +1, sbuffer, 12000);

MsgSendv (coid, siov, 2, riov, 1);

Для приема сообщения клиента сервер файловой системы должен сделать так:

// Настроить структуру IOV для приема:

SETIOV (iov +0, header, sizeof (header));

SETIOV (iov +1, cache-buffer [37], 4096);

SETIOV (iov +2, cache-buffer [16], 4096);

SETIOV (iov +3, cache-buffer [22], 4096);

rcvid = MsgReceivev (chid, iov, 4, NULL);

Эта программа задает вектор IOV из 4 частей, первая из которых указывает на заголовок, а следующие три части — на блоки кэш-памяти с номерами 37, 16 и 22.

Но в общем случае мы должны заголовок принять отдельно, а затем задать вектор IOV из 3 частей.

// Настроить структуру IOV для приема:

SETIOV (iov +0, cache-buffer [37], 4096);

SETIOV (iov +1, cache-buffer [16], 4096);

SETIOV (iov +2, cache-buffer [22], 4096);

MsgReceive (chid, header, sizeof (header), NULL);

switch (header.message_type)

{

case _IO_WRITE:

number_of_bytes - header.io_write.nbytes;

// Выделить / найти элемент кэша

// Заполнить элементы кэша 3-элементным IOV

MsgReadv (rcvid, iov, 3, sizeof (header.io_write|);

…………………………………………………………..

}

Возможные действия сервера в ответ на запрос чтения:

1. Найти элементы кэша, которые соответствуют запрашиваемым данным.

2. Заполнить вектора IOV ссылками на них.

3. Применить функцию MsgWritev() (или MsgReplyv()) для передачи данных клиенту.

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

Функция Буфер передачи Буфер приема

MsgSend()

линейный

линейный

MsgSendnc()

линейный

линейный

MsgSendsv()

линейный

IOV

MsgSendsvnc()

линейный

IOV

MsgSendvs()

IOV

линейный

MsgSendvsnc()

IOV

линейный

MsgSendv()

IOV

IOV

MsgSendvnc()

IOV

IOV

Функции MsgSendsv() и MsgSendsvnc() идентичны только по части параметров. Различие заключается в том, что функция с суффиксом «nc» (no cancellation») ) не являются точками завершения, в то время как версии без этого суффикса — являются.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]