projetando servidores concorrentes genéricos em c++0x

24
Universidade do Estado do Rio de Janeiro Instituto 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ão Orientador: Alexandre Sztajnberg Abril 2009

Upload: pedrolamarao

Post on 25-Jun-2015

128 views

Category:

Documents


0 download

DESCRIPTION

Monografia apresentada para conclusão do curso de Bacharelado em Informática e Ciência da Computação no Instituto de Matemática e Estatística da Universidade do Estado do Rio de Janeiro.

TRANSCRIPT

Page 1: Projetando Servidores Concorrentes Genéricos em C++0x

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

Page 2: Projetando Servidores Concorrentes Genéricos em C++0x

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

Page 3: Projetando Servidores Concorrentes Genéricos em C++0x

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

Page 4: Projetando Servidores Concorrentes Genéricos em C++0x

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

Page 5: Projetando Servidores Concorrentes Genéricos em C++0x

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– ..?

Page 6: Projetando Servidores Concorrentes Genéricos em C++0x

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);

Page 7: Projetando Servidores Concorrentes Genéricos em C++0x

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);

Page 8: Projetando Servidores Concorrentes Genéricos em C++0x

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);

}

Page 9: Projetando Servidores Concorrentes Genéricos em C++0x

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);

Page 10: Projetando Servidores Concorrentes Genéricos em C++0x

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...

Page 11: Projetando Servidores Concorrentes Genéricos em C++0x

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

Page 12: Projetando Servidores Concorrentes Genéricos em C++0x

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.};

Page 13: Projetando Servidores Concorrentes Genéricos em C++0x

C++0x

class socket {

template <typename AddressType>requires SocketAddress<AddressType>voidbind (AddressType const& address);

voidlisten (int backlog = SOMAXCONN);

socketaccept ();

};

Page 14: Projetando Servidores Concorrentes Genéricos em C++0x

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);

Page 15: Projetando Servidores Concorrentes Genéricos em C++0x

POSIX/C++ Sockets

sockaddr_in addr;addr.sin_family = AF_INET;addr.sin_port = htons(7);addr.sin_addr.s_addr = htonl(IPADDR_ANY);

Page 16: Projetando Servidores Concorrentes Genéricos em C++0x

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));

}

Page 17: Projetando Servidores Concorrentes Genéricos em C++0x

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?

Page 18: Projetando Servidores Concorrentes Genéricos em C++0x

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.

Page 19: Projetando Servidores Concorrentes Genéricos em C++0x

Servidor Genérico: Modelo

Page 20: Projetando Servidores Concorrentes Genéricos em C++0x

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

Page 21: Projetando Servidores Concorrentes Genéricos em C++0x

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

Page 22: Projetando Servidores Concorrentes Genéricos em C++0x

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

Page 23: Projetando Servidores Concorrentes Genéricos em C++0x

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

Page 24: Projetando Servidores Concorrentes Genéricos 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