From: Б.А. Державец <dba477 at list.ru>
Newsgroups: email
Date: Mon, 07 May 2004 14:31:37 +0000 (UTC)
Subject: Реализация многопотокового "ассинхронного сервра TCP" и RPC для ОС Linux
РЕАЛИЗАЦИЯ МНОГОПОТОКОВОГО "АСИНХРОННОГО СЕРВЕРА TCP" И RPC ДЛЯ ОС LINUX
-------------------
В заметке приводится код многопотокового эхо-сервера , основанного
на использовании неблокирующего ввода вывода и конечных автоматов.
Каждый поток сервера использует вызов select( ) для того, чтобы определить
по какому из соединений можно производить обмен в данный момент
времени.
Код для процедуры serv_request , выполняемой ведомыми потоками может
быть взят из различных источников ( см. [1],[2],[3]). Параметр ,
передаваемый в процедуру serv_request , явлется дескриптором пассивного
сокета , создаваемый ведущим потоком с помощью вызова процедуры
getServerSocket( ).
Необходимо отметить, что приведенное решение основано на свойстве Linux
эффективно распараллеливать вызов accept( ). В противном случае
возникает необходимость в блокировке мьютекса перед вызовом accept( ),
что влечет за собой последовательное выполнение потоками сервера
критической части кода, т.е. вызова accept( ).
В среде же Red Hat Linux 9 (например) эта предосторожность не нужна и
только снижает производительность.
Детальное описание Posix Threads API на русском языке может быть
найдено в [2]. Приводится также модифицированный код заглушки
sample_svc.c (не за- висящий от шаблона sample.x) , позволяюший
скомпилировать многопото- ковый сервер RPC в среде LINUX.
void
bark(const char *func, int err)
{
fprintf(stderr,"%s: %sn",func, strerror(err));
}
/*
Описание поцедуры ведущего потока , которая возвращает
дескрипторов пассивного сокета, привязанного к адресу
сервера.
*/
int
getServerSocket(unsigned short int port)
{
int listenSocket;
struct sockaddr_in listenSockaddr;
/*
Проверка принадлежности дескриптора
(*currentConnPtr)->dataSocket к множеству readFdSet
*/
if((*currentConnPtr)->isReading &&
FD_ISSET((*currentConnPtr)->dataSocket,&readFdSet))
{
int result = recv((*currentConnPtr)->dataSocket, (*currentConnPtr)->data,
sizeof((*currentConnPtr)->data),0);
Thread id = '1082453184' started, arg = 14
Thread id = '1090841664' started, arg = 15
Thread id = '1099230144' started, arg = 16
Thread id = '1116941120' started, arg = 17
Thread id = '1125329600' started, arg = 11
Thread id = '1133718080' started, arg = 12
Thread id = '1142106560' started, arg = 21
Thread id = '1150495040' started, arg = 13
Thread id = '1158883520' started, arg = 10
Thread id = '1167272000' started, arg = 18
Thread id = '1175660480' started, arg = 19
Thread id = '1184048960' started, arg = 20
Thread id = '1082453184' is done 196
Thread id = '1090841664' is done 225
Thread id = '1099230144' is done 256
Thread id = '1116941120' is done 289
Thread id = '1125329600' is done 121
Thread id = '1133718080' is done 144
Thread id = '1142106560' is done 441
Thread id = '1150495040' is done 169
Thread id = '1158883520' is done 100
Thread id = '1167272000' is done 324
Thread id = '1175660480' is done 361
Thread id = '1184048960' is done 400
Литература
1. Дуглас Э. Крамер,Дэвид Л. Стивенс. Сети TCP/IP .Разработка приложений Типа
клиент/сервер для LINUX/POSIX . Том 3 Издательский дом "Вильямс",2002
2. http://dlenev.nm.ru/
3. Стивенс У. UNIX: Взаимодействие процессов.Том 1,2 Из-во "Питер",2002
893 Прочтений • [Реализация многопотокового "ассинхронного сервра TCP" и RPC для ОС Linux (select thread rpc gcc socket)] [08.05.2012] [Комментариев: 0]