Операционная система UNIX
В качестве примера виртуального копирования можно привести реализацию протокола TCP. Протокол TCP является надежным, т.е. данные считаются доставленными только после того, как от получателя поступит подтверждение. Это означает, что протокол должен хранить копии всех отправленных, но не подтвержденных сообщений. Вместо неэффективного физического копирования, производится виртуальное дублирование сообщения, одна копия которого затем передается вниз по потоку (модулю IP), а вторая сохраняется до получения подтверждения. После отправления сообщения драйвером сетевого адаптера, одна из копий будет уничтожена, что выразится в уменьшении поля
заголовка блока данных, но сам блок данных сохранится, поскольку значение счетчика по-прежнему будет превышать 0. И только после получения подтвержденияdb_refстанет равным 0, и соответствующий буфер будет освобожден.db_refТипы сообщений
Каждое сообщение принадлежит определенному типу, определяющему назначение сообщения и его приоритет. В зависимости от типа сообщения попадают в одну из двух категорий: обычные сообщения и приоритетные сообщения. Категория определяет порядок, в котором сообщения будут обрабатываться соответствующей процедурой
. Приоритетные сообщения всегда помещаются перед обычными сообщениями и потому обрабатываются в первую очередь.<i>xx</i>service()В подсистеме STREAMS определены следующие типы обычных сообщений:
M_DATAСодержит обычные данные. Например, системные вызовы read(2) и write(2) осуществляют передачу данных в виде сообщений этого типа. M_PROTOСодержит управляющую информацию. Обычно сообщение этого типа содержит также несколько блоков типа . С помощью системных вызовов putmsg(2) и getmsg(2) процесс имеет возможность отправлять и получать как управляющую часть сообщения (блокM_DATA), так и данные (блокиM_PROTO).M_DATAM_BREAKПосылается драйверу устройства для генерации команды break. M_PASSFPИспользуется в каналах STREAMS (STREAMS pipe) для передачи файлового указателя от одного конца канала к другому. M_SIGГенерируется модулями или драйверами и передается вверх по потоку головному модулю для отправления процессу сигнала. M_DELAYПередается драйверу устройства и указывает задержку между последовательно передаваемыми символами. Как правило, используется при работе с медленными устройствами во избежание переполнения их буферов. M_CTLИспользуется для взаимодействия модулей потока друг с другом. Все сообщения этого типа уничтожаются головным модулем и, таким образом, не могут распространяться за пределы потока. M IOCTLФормируется головным модулем в ответ на управляющие команды, переданные процессом с помощью системного вызова ioctl(2): ,I_LINK,I_UNLINK,I_PLINKиI_PUNLINK. Эти команды используются для создания мультиплексированных потоков. Последняя команда используется для управления модулями потока.I_STRM_SETOPTSИспользуется для задания различных характеристик головного модуля. M_RSEЗарезервировано для внутреннего использования. Модули и драйверы должны передавать его без изменений. Как мы увидим далее, на передачу обычных сообщений влияет механизм управления потоком данных, который может быть реализован модулями потока. Этот механизм не оказывает влияния на передачу приоритетных сообщений. Сообщения этой категории будут переданы следующему модулю, независимо от того, насколько заполнена его очередь. Эти сообщения обеспечивают основное взаимодействие между компонентами потока. Перечисленные ниже сообщения являются высокоприоритетными:
M_COPYINПередается вверх по потоку головному модулю и указывает ему скопировать данные от процесса для команды ioctl(2). Сообщение допустимо в интервале между получением сообщения и сообщенияM_IOCTLилиM_IOCACK.M_IOCNAKM_COPYOUTПередается вверх по потоку головному модулю и указывает ему передать данные, связанные с вызовом ioctl(2), процессу. Сообщение допустимо в интервале между получением сообщения и сообщенийM_IOCTLилиM_IOCACK.M_IOCNAKM_ERRORПередается вверх по потоку головному модулю и указывает на возникновение ошибки вниз по потоку. Последующие операции с потоком будут заканчиваться ошибкой, за исключением системных вызовов close(2) и poll(2). M_FLUSHПри получении этого сообщения модуль должен очистить очередь (чтения, записи или обе) от сообщений. M_HANGUPПередается вверх по потоку головному модулю и указывает, что драйвер не может передавать данные, обычно из-за обрыва линии (связи с удаленным объектом). M_IOCACKПодтверждение предыдущего сообщения . В ответ головной модуль возвратит необходимые данные процессу, сделавшему системный вызов ioctl(2).M_IOCTLM_IOCNAKЕсли выполнение команды ioctl(2) закончилось неудачей, это сообщение передается вверх по потоку головному модулю, в ответ на это последний возвратит процессу ошибку. M_PCPROTOВысокоприоритетная версия сообщения .M_PROTOM_PCSIGВысокоприоритетная версия сообщения .M_SIGM_PCRSEЗарезервировано для внутреннего использования в подсистеме. M_READСообщение передается вниз по потоку, когда от процесса поступает запрос на чтение, но в головном модуле отсутствуют данные. M_STOPПредписывает немедленно прекратить передачу. M_STARTПредписывает продолжить передачу после останова, вызванного сообщением .M_STOP