projetando servidores concorrentes genéricos em c++0x
Post on 25-Jun-2015
127 Views
Preview:
DESCRIPTION
TRANSCRIPT
Universidade do Estado do Rio de JaneiroInstituto de Matemática e Estatística
Departamento de Informática e Ciência da Computação
Projetando Servidores Concorrentes Genéricos em C++0x
Aluno: Pedro LamarãoOrientador: Alexandre Sztajnberg
Abril 2009
Roteiro
● Introdução
● Objetivos
● Interface de Programação de Sockets POSIX
● Mecanismos de Projeto e Implementação do C++0x
● Um Binding POSIX/C++ para a Interface de Sockets
● Projetando Servidores Concorrentes em C++
● Exemplo
● Considerações Finais
Introdução
● Estratégias de Concorrência para Servidores como atender a múltiplos clientes simultaneamente
● Mecanismos de Concorrência em POSIXcomo ler e escrever de/para múltiplos dispositivos de I/O simultaneamente
● Mecanismos de Abstração em C++0xpodemos utilizar abstrações mais confortáveis para tratar os problemas acima
Objetivos● Desenvolver um binding POSIX/C++ para sockets
– Interface mais “limpa”:● orientação a objetos● programação genérica● uma implementação de referência
● Propor um padrão para projeto de servidores concorrentes em C++– Estratégias de concorrência– Servidores concorrentes genéricos– Handlers genéricos– Implementação de referência
POSIX/C Sockets
● POSIX é uma norma que especifica a interface de programação entre sistema operacional e programas de usuário
● POSIX/C é POSIX na linguagem C● Sockets são dispositivos para comunicação entre
processos● A programação de servidores concorrentes
utilizando sockets em C possui limitações:– verificação tediosa de erros– informação com mínima tipagem– ..?
POSIX/C Sockets
struct addrinfo hint ={ AI_PASSIVE, AF_INET, SOCK_STREAM, 0, 0, 0, 0,
0 };struct addrinfo* ai;int st = getaddrinfo("", "echo", &hint, &ai);if (st != 0) {
fprintf(stderr, "%s\n", gai_strerror(status));exit(1);
}
sockaddr_storage addr;memcpy(&addr, ai->ai_addr, ai->ai_addrlen);socklen_t addrlen = ai->ai_addrlen;
freeaddrinfo(ai);
POSIX/C Sockets
sockaddr_in addr;addr.sin_family = AF_INET;addr.sin_port = htons(7);addr.sin_addr.s_addr = htonl(IPADDR_ANY);socklen_t addrlen = sizeof(sockaddr_in);
POSIX/C Sockets
int listener = socket(AF_INET, SOCK_STREAM, 0);if (listener == -1) {
perror(NULL);exit(1);
}
st = bind(listener, (struct sockaddr*)&addr, addrlen);if (status == -1) {
perror(NULL);exit(1);
}
st = listen(listener, SOMAXCONN);if (status == -1) {
perror(NULL);exit(1);
}
POSIX/C Sockets
is_running = 1;while (is_running) {
int client = accept(listener, NULL, 0);if (client == -1) {
perror(NULL);exit(1);
}
echo_handler(client);}
close(listener);
C++0x
C++ é Ccom melhores mecanismos de abstração
C++ e C são normas ISO
C++0x é a nova revisão da norma C++
Provavelmente será C++1x quando terminar...
C++0x
● Vantagens do C++0x– exceções para propagação de erros– classes para representação de recursos– templates para programação genérica
● Como posso utilizar estas vantagens para fazer melhores programas concorrentes utilizando sockets?– exceções para evitar o tédio– classes para gerência de recursos– funções parametrizadas no tipo do endereço– listas de objetos adequadas aos algoritmos genéricos
C++0xclass socket {public:
socket ();socket (int family, int socktype, int protocol =
0);
socket (socket const& x) = delete; socket (socket&& x);
~socket ();
socket& operator= (socket const& x) = delete;socket& operator= (socket&& x);
// etc.};
C++0x
class socket {
template <typename AddressType>requires SocketAddress<AddressType>voidbind (AddressType const& address);
voidlisten (int backlog = SOMAXCONN);
socketaccept ();
};
POSIX/C++ Sockets
O mesmo exemplo anterior, reescrito em C++0x
addrinfo hint ={ AI_PASSIVE, AF_INET, SOCK_STREAM, 0, 0, 0, 0,
0 };
auto result = posix::getaddrinfo("", "echo", hint);addrinfo const& ai = *(result.begin());
sockaddr_storage addr;memcpy(&addr, ai.ai_addr, ai.ai_addrlen);
POSIX/C++ Sockets
sockaddr_in addr;addr.sin_family = AF_INET;addr.sin_port = htons(7);addr.sin_addr.s_addr = htonl(IPADDR_ANY);
POSIX/C++ Sockets
posix::socket listener(AF_INET, SOCK_STREAM);
listener.bind(addr);
listener.listen();
is_running = 1;while (is_running) {
posix::socket client = listener.accept();
echo_handler(std::move(client));
}
POSIX/C++ Sockets
● O que ganhei com o Binding?● Exceções propagam erros automaticamente; o
responsável que capture e trate● Notação mais elegante economiza argumentos em
chamadas● Gerência de recursos evita vazamentos● Programação Genérica sugere reuso...
– agora com uma classe socket reusável, o que seria uma classe servidor reusável?
Servidor Genérico
● Um template de classes é uma regrapara geração mecânica de classes
● Uma classe genérica é uma meta-classe, especializável por outras classes,que definem seu comportamento
● Uma estratégia é reaplicável,assim como uma meta-classe...
● ...em tempo de compilação, não de execução.
Servidor Genérico: Modelo
Servidor Genérico: Modelo
● server encapsula o modo de uso de um mecanismo de concorrência qualquer
● StrategyServer especifica a relação entre server e StrategyHandlers
● foo_handler implementa o protocolo de aplicação foo, obedecendo a StrategyHandler
● server<foo_handler> gera mecanicamenteclasses servidor-do-protocolo-foo
Servidor Genérico: Estratégia
● Inicialmente, um loop: uma iteração, um cliente● Concorrência com threads ou processos:
iteração/cliente inicia novo● thread● processo
● Concorrência com notificação de disponibilidade:um “demultiplexador” mantém múltiplos clientes ● select● poll
Servidor Genérico: Aplicação
typedef echo_threaded_handler handler;threaded_server<handler> server;
addrinfo hint ={ AI_PASSIVE, AF_INET, SOCK_STREAM, 0, 0, 0, 0,
0 };auto result = posix::getaddrinfo("", "echo", hint);
server.configure(*result.begin());
server.start();
server(); // main loop
Conclusão
● POSIX/C possui mecanismos adequados para implementar a concorrência
● C++0x possui mecanismos adequados para tornar a implementação mais... confortável
● É possível escrever estratégias de concorrência como meta-classes em C++0x
Trabalhos Futuros
● Estratégia: concorrência com notificação de finalização de operação
● Avaliação de Desempenho
● Handlers para protocolos de aplicação mais complexos
● Proposta formal no grupo de trabalho
top related