Главная страница Взаимодействие нетривиальных процессов Новый аргумент в вызове процедуры 12-14 Вторым аргументом вызова squareproc 2 становится указатель на переменную out, а последним аргументом является дескриптор клиента. Вместо возвращения указателя на результат (как в листинге 16.2) эта функция будет возвращать либо RPC SUCCESS, либо некоторое другое значение в случае возникновения ощибок. Перечисление enum cl nt stat в заголовочном файле <грс/с1 nt stat. h> содержит все возможные коды ощибок. В листинге 16.6 приведен текст новой процедуры сервера. Как и программа из листинга 16.4, эта версия выводит идентификатор потока, ждет 5 секунд, а затем завершает работу. Листинг 16.6. Процедура многопоточного сервера sunrpc/squareS/server.c 1 #include unpipc.h 2 #include square.h 3 bool t 4 squareproc 2 svc(square in *inp. square out *outp. struct svc req *rqstp) 6 printfC thread %d started, arg = ld\n , 7 pr thread id(NULL), inp->argl): 8 sleep(5): 9 outp->resl = inp->argl * inp->argl; 10 printfC thread Id-doneXn . pr thread id(NULL)): 11 return(TRUE); 12 } 13 int 14 square prog 2 freeresult(SVCXPRT *transp, xdrproc t xdr result, 15 caddr t result) 16 { 17 xdr free(xdr result, result); 18 return(l): 19 } Новые аргументы и возвращаемое значение 3-12 Требуемые для реализации многопоточности изменения включают изменение аргументов функций и возвращаемого значения. Вместо возвращения указателя на структуру результатов (как в листинге 16.3) указатель на эту структуру принимается в качестве второго аргумента функции. Указатель на структуру svc req смещается на третью позицию. Теперь при успешном завершении функции возвращается значение TRUE, а при возникновении ошибок - FALSE. Новая функция, освобождающая память XDR 13-19 Еще одно изменение заключается в добавлении функции, освобождающей все автоматически выделенные переменные. Эта функция вызывается из заглушки сервера после завершения работы процедуры сервера и отправки результата клиенту. В нашем примере просто делается вызов подпрограммы xclr f гее (о ней будет говориться более подробно в связи с листингом 16.19 и упражнением 16.10). Если процедура сервера выделяла память под сохраняемый результат (например, в виде связного списка), этот вызов освободит занятую память. Создадим программу-клиент и программу-сервер и запустим три экземпляра клиента одновременно: Solaris X client local host 55 & client local host 66 & client local host 77 & [3] 25427 [4] 25428 [5] 25429 Solaris X result: 4356 result: 3025 result: 5929 Ha этот раз мы видим, что результаты выводятся одновременно, один за другим. Взглянув на выводимый сервером текст, отметим, что используются три серверных потока и все они выполняются одновременно: Solaris X server thread 1 started, arg 55 thread 4 started, arg = 77 thread 6 started, arg = 66 thread 6 done thread 1 done thread 4 done ПРИМЕЧАНИЕ- Одним из печальных следствий изменений, требуемых для реализации многопоточности, является уменьшение количества систем, поддерживающих новый код. Например, в Digital Unix 4.0В и BSD/OS 3.1 используется старая система RPC, не поддерживающая многопоточность. Это означает, что если мы хотим компилировать и использовать нашу профамму в системах обоих типов, нам нужно использовать условия #ifdef для обработки различий в вызовах клиента и сервера. Конечно, клиент в BSD/OS, не являющийся многопоточным, может вызвать процедуру многопоточного сервера в Solaris, но если мы хотим, чтобы клиент или сервер компилировался в обоих типах систем, исходный код нужно изменить, предусмотрев различия. 16.3. Привязка сервера в описании листинга 16.5 мы достаточно бегло прошлись по действиям, выполняемым на нулевом этапе: регистрация сервера в локальной программе отображения портов и определение клиентом адреса порта не были разобраны детально. Отметим прежде всего, что на любом узле с сервером RFC должна выполняться программа port mapper (отображение портов). Этой программе присваивается адрес порта TCP 111 и UDP 111, и это единственные фиксированные значения портов Интернета для Sun RPC. Серверы RPC всегда связываются с временным портом, а затем регистрируют его в локальной службе отображения портов. После запуска гслиент должен связаться с программой отображения портов, узнать номер временного порта сервера, а затем связаться с самим сервером через этот порт. Программа отображения портов предоставляет также службу имен, область действия которой ограничена системой. ПРИМЕЧАНИЕ- Некоторые читатели могут возразить, что сетевая файловая система также имеет фиксированный номер порта 2049. Хотя во многих реализациях по умолчанию действительно используется именно этот порт, а в некоторых старых реализациях он вообще жестко зашит в клиентскую и серверную части NFS, большинство существующих реализаций позволяют использовать и другие порты. Большая часть клиентов NFS также связывается со службой отображения портов для 1юлучения номера порта. В Solaris 2.x Sun переименовала службу отображения портов в RPCBIND. Причина этого изменения заключается в том, что термин порт подразумевает порт Интернета, тогда как пакет TI-RPC может работать с любым сетевым протоколом, а не только с TCP и UDP. Мы будем использовать традиционное название программа отображения портов (port mapper). Далее в этой главе мы будем подразумевать, что на данном узле поддерживаются только протоколы TCP и UDP. Сервер и клиент работают следующим образом: 1. При переходе системы в многопользовательский режим запускается программа отображения портов. Исполняемый файл этого демона обычно называется portmap или rpcbind. 2. При запуске сервера его функция mai п, являющаяся частью заглущки сервера, создаваемой rpcgen, вызывает библиотечную функцию svc create. Эта функция выясняет, какие сетевые протоколы поддерживаются узлом, и создает конечную точку (например, сокет) для каждого протокола, связывая временные порты с конечными точками протоколов TCP и UDP. Затем она связывается с локальной программой отображения портов для регистрации временных номеров портов TCP и UDP вместе с номером программы и номером версии. Сама программа отображения портов также представляет собой программу RPC, и сервер регистрируется с помощью вызовов RPC (обращенных к известному порту 111). Описание процедур, поддерживаемых программой отображения портов, дается в стандарте RFC 1833 [20]. Существуют три версии этой программы RPC: вторая версия работает только с портами TCP и UDP, а версии 3 и 4 представляют собой новые версии, работающие по протоколу RPCBIND. Можно ползд1ить список всех программ RPC, зарегистрированных в программе отображения портов, запустив программу rpcinfo. Мы можем запустить эту программу, чтобы убедиться, что порт с номером 111 используется самой программой отображения портов:
(Мы исключили множество несущественных в данный момент строк вывода.) Мы видим, что Solaris 2.6 поддерживает все три версии протокола, все
|
© 2000 - 2024 ULTRASONEX-AMFODENT.RU.
Копирование материалов разрешено исключительно при условии цититирования. |