Chamadas bloqueantes
Last updated
Last updated
Quando um programa precisa fazer uma chamada no I/O, a CPU sofre uma interrupção para ser liberada para outro programa do computador e o processo atual fica bloqueado. É por isso que chamamos de I/O bloqueante.
Durante a leitura do arquivo, a thread não faz outra coisa. Se for a thread principal do processo, o programa todo fica bloqueado até que a leitura do I/O seja concluída.
Dependendo das características do sistema, isto pode trazer problemas de performance. Se por exemplo, múltiplos requests HTTP chegam no servidor, a latência total da aplicação será muito alta, fazendo com que diversos requests fiquem travados na fila.
Uma solução? Disparar uma thread para cada requisição HTTP:
Desta forma, enquanto uma thread fica bloqueada esperando I/O, outra pode fazer uso da CPU ou mesmo de outro recurso de I/O.
Yay! Problema resolvido, certo Leandro?
Calma, jovem.
Problemas com esta abordagem: a criação de thread no SO tem seus custos. No caso de termos milhares de requisições, terminaríamos com a criação de milhares de threads, apenas para atender as requisições HTTP de um sistema. E quanto aos outros programas do computador?
O sistema operacional define um limite de threads para serem criadas. Criar thread não deveria ser algo banal, temos que criar threads com muita parcimônia.
Uma forma de resolver esta criação absurda de threads é definir uma "piscina" de threads, com um número limitado, onde estas threads seriam recicladas para todos os pedidos que chegassem na aplicação.
Sim, estamos falando de pool de threads.
A definição de uma pool de threads pode ser implementada com qualquer linguagem de programação. Basta ter uma fila, onde os pedidos são enfileirados; e depois a definição de um número fixo de threads que ficam consumindo os pedidos da fila. Ao término, a thread volta a esperar algo na fila.
Pool de threads resolve a limitação de criação de threads no SO e evita com que utilizemos recursos de forma desnecessária. Entretanto, para lidar com chamadas no I/O, precisamos mesmo bloquear as threads?
E se houvesse um mecanismo no SO, bem inteligente, que permite que as chamadas no I/O possam ser não-bloqueantes, notificando assim o programa quando o recurso ficar pronto?