Chamadas não-bloqueantes
Last updated
Last updated
O sistema operacional fornece um recurso muito interessante de chamadas não-bloqueantes em I/O. Desta forma, o programa recebe imediatamente um file descriptor que representa o I/O solicitado, e depois recorre a recursos do sistema operacional para verificar quando o recurso está pronto. Assim, o programa não fica bloqueado.
Esta é a definição de assincronismo, ou I/O assíncrono.
Em Linux, chamadas de sistema como select ou epoll permitem controlar I/O assíncrono. Com select o programa verifica quais descritores estão prontos, enquanto que no epoll, o SO notifica o programa através de uma fila quais descritores estão prontos.
Também não vamos por enquanto entrar nos detalhes do uso de select ou epoll, isto fica numa seção futura neste guia quando entrarmos na parte de implementação. Aqui, é importante entendermos os conceitos.
De qualquer forma, o programa, seja ele qual for, não precisa usar multi-thread para lidar com I/O - a não ser que realmente queira. Com apenas uma thread, é possível criar um "loop" que fica verificando no SO quais chamadas ficaram prontas.
Vamos, em pseudocódigo, escrever um loop com este propósito:
Enfim, a ideia aqui é ilustrar como seria um loop de eventos hipotético, que tanto ouvimos falar:
iniciar loop
passar para o select (ou epoll) a lista de descritores que queremos monitorar
ler os descritores que estão prontos para leitura
escrever nos descritores que estão prontos para escrita
repetir o loop infinitamente
Repare que, ao termos um loop assíncrono de eventos, é extremamente importante toda e qualquer chamada ser não-bloqueante, caso contrário, se tivermos ao menos uma chamada bloqueante, o loop todo ficará bloqueado, e consequentemente a thread ficará bloqueada.
Lembrem-se, com I/O assíncrono nunca podemos bloquear o loop. Toda chamada no I/O deve ser assíncrona.