feito uma operacao de leitura. Neste momento NAO ha nada para ser lido. Nesse caso, podem acontecer duas coisas:1) Esperar ate que uma resposta seja dada pelo servidor (blocking)2) Retornar imediatamente um erro dizendo que nao ha informacoes para serem lidas (non-blocking) OBS: quando falo em resposta, nao me refiro repsota para o usuario final, mas sim em baixo nivel mesmo.BlockingComportamento comum dos servidores. Voce chama uma operacao "read()" e o programa fica esperando ate que uma resposta seja dada.Non-BlockingExistem duas formas de trabalhar com Non-Blocking I/O.1) Fazendo polling, que e ficar tentando ler alguma coisa a cada X tempo.2) Utlizar notificacao assincrona. Isso significa que o servidor ira gerar um evento infornado que existe coisa para ser lida.O SO gera um evento informando que o socket/FD esta pronto para ser lido?? Como???Como sao feitos Non-blockings I/OVou explicar alguns recursos do SO que "produzem" os non-blockings I/O. Esses sao os comandos que o SO prove para voce saber quando tem algo para ser lido em um socket/FD.Ao longo do tempo alguns comandos surgiram e forao substituidos: "Select", "Poll", "Dev/Poll", "epoll" e "kqueue". Cada sistema operacional tem seus proprios comandos.poll0O comando poll() avisa quando um conjunto de FDs esta pronto para ser lido. Esse comando fica lento quando se tem milhares de FDs, pois muitos dos FDs podem estar idle (ocioso) e varrer todos leva muito tempo.Se nada for lido nesse File Descriptor, o proximo comando Poll vai dizer que ainda tem coisa para ser lida.dev/pollCom este comando voce avisa o SO apenas uma fez quais os FD voces esta interessado. Voce faz isso com um "handler". A partir dai voce le um conjunto de FDs prontos para serem lidos, apartir desse "handler".Esse comando foi cirado para subistituir o poll() no Solaris. Nao e recomendada sua utlizacao no Linux. epoll()Esse e o comando que subistitui o poll() na versao 2.6 do Kernel do Linux. Ele agrupa eventos redundantes e tem trabalha the forma eficiente com eventos em massa, fazendo que tenha uma otima escalabilidade quando utilizado com grande numero de FDs.Ele pode ser utilizado com edge-triggered e level-triggered, que sao formas de interrupcoes utilizadas para otimizar a utlizacao de CPU.kqueue()/kevent()Esse comando e similiar com o epoll(). Na verdade foi criado antes dele, mas para o FreeBSD. O pessoal do Linux criou um novo comando ao inves de uitlizar este.Estrategias de I/OUm pouco mais embasado, podemos olhar algumas estrategias de implementar um servidor. Usando non-blocking, usando threads, etc.Isso e uma copia direta desse link.Como utitilizar deversas chamadas de I/O para uma simples thread.Nao usar blocking I/O e se possivel usar multi-threading e processos para alcancar concorrencia. Usar chamadas non-blocking (ex: write() em um socket setado O_NONBLOCK) para iniciar o I/O, e as notificacoes de leitura de eventos (e.g. poll() ou /dev/poll) para saber quando o canal esta pronto para leitura. Usar chamadas assincronas para comecar o I/O e notificacoes de de encerramento do I/O.Como controlar o codigo de cada clienteUm processo para cada cliente (abordagem classica do Unix)Uma thread no SO lida com varios clientes. Cada cliente pode ser controlado por: user-level thread state