Считать данные из сообщения
#include <sys/neutrino.h>
int MsgRead( int rcvid,
void *msg,
int bytes,
int offset );
int MsgRead_r( int rcvid,
void *msg,
int bytes,
int offset );
- rcvid
- Идентификатор сообщения, возвращаемый потоку-серверу функцией MsgReceivev*() при приеме сообщения.
- msg
- Указатель на буфер, в котором функция будет сохранять данные.
- bytes
- Количество байт, которые необходимо прочитать. При этом функция возвращает количество байт, которые реально считаны.
- offset
- Смещение относительно начала отправленного сообщения. Указывает, откуда надо начинать чтение данных.
libc
Функции MsgRead() и MsgRead_r() вычитывают данные из сообщения, отправленного потоком, идентифицированным rcvid. Выполнение чтения возможно до отправки клиенту ответа. Клиент будет находиться в REPLY-блокированном состоянии. Выполнять чтение сообщения может любой поток процесс-получателя.
Данные функции идентичны за исключением способа возврата ошибок.
Передача данных выполняется немедленно, поток-читатель не блокируется. Состояние потока-отправителя не меняется.
Данные функции используются в следующих ситуациях:
- Отправленное сообщение включает фиксированный заголовок и переменное количество данных. В заголовке содержится значение размера данных. Если данные большие и должны быть размещены в одном или нескольких буферах (например, в кэше файловой системы), то вместо того, чтобы получать их в один большой буфер, а затем копировать в другие буферы, удобнее с помощью MsgReceive() получить только заголовок, а затем вызвать MsgRead() один или несколько раз, чтобы считать данные в необходимые буферы.
- Сообщение получено, но пока не может быть обработано. Позже должно произойти событие, позволяющее обработать данные. Вместо того, чтобы хранить сообщение до обработки, используя ОЗУ, можно перечитать его с помощью MsgRead() пока отправитель остаётся заблокированным.
- Сообщения имеют размер больше, чем доступные буферы. Например, такое может быть в ситуации, когда процесс является агентом между двумя процессами и просто выполняет фильтрацию данных. Сообщение можно читать небольшими фрагментами с помощью MsgRead*() и записывать небольшими фрагментами с помощью MsgWrite*().
После использования MsgRead() необходимо вызвать MsgReply*(), чтобы разблокировать REPLY-блокированного клиента и завершить обмен сообщениями.
Отсутствует. В случае сетевого взаимодействия может получить управление поток с меньшим приоритетом.
Функция MsgRead() имеет повышенную задержку при сетевом взаимодействии, поскольку в этом случае сообщение передается от сервера к сетевому менеджеру. В зависимости от размера передаваемых данных серверному lsm-qnet.so
и клиентскому lsm-qnet.so
для чтения данных от клиента может потребоваться взаимодействие через канал связи.
- MsgRead()
- Число считанных байт данных. Если возникла ошибка функция возвращает
-1
, код ошибки записывается в errno.
- MsgRead_r()
- Число считанных байт данных. Функция НЕ устанавливает errno. При возникновении ошибки функция возвращает один из представленных ниже кодов.
При попытке чтения данных больше, чем размер доступного буфера, функция вернет количество реально прочитанных байт.
- EFAULT
- Ошибка в адресном пространстве сервера при попытке доступа к буферам отправленного сообщения.
- ESRCH
- Поток, ассоциированный с rcvid не существует или отключил соединение от канала.
- ESRVRFAULT
- Ошибка при попытке ядра получить доступ к предоставленным буферам.
ЗОСРВ «Нейтрино»
- Нет
- Обработчик прерываний
- Нет
- Обработчик сигналов
- Да
- В потоке
- Да
MsgReadv(), MsgReceive(), MsgReceivev(), MsgReply(), MsgReplyv(), MsgWrite(), MsgWritev()
Предыдущий раздел: Описание API системной библиотеки