You are on page 1of 2

IO Síncrono vs.

Assíncrono
• Síncrono
– A aplicação pára à espera da execução do pedido de IO pelo sistema (incluindo a execução
do driver)
• Assíncrono
– A função de IO termina de imediato, e a aplicação prossegue a execução
– O pedido de IO fica em fila de espera, e é depois enviado pelo sistema ao driver
– Quando o driver completa o pedido, o sistema notifica a aplicação
• Implementação assíncrona divide-se em
– Envio dos pedidos de IO (ReadFile, WriteFile...)
– Recepção das notificações de conclusão dos pedidos
• Enviar pedidos de IO assíncronos
– A função CreateFile(...) tem que ser invocada especificando a flag
FILE_FLAG_OVERLAPPED
– É necessário passar no parâmetro ‘pOverlapped’ o endereço de uma estrutura
OVERLAPPED inicializada, que identifica o pedido
• membros Offset e OffsetHigh têm que ser zero para dispositivos diferentes de ficheiros
• membro hEvent é utilizado pelo 2º método de recepção de notificações (ver próximo slide)
– A invocação da função de IO dá erro e é necessário verificar qual é ele, invocando
GetLastError()
• Se o resultado é ERROR_IO_PENDING significa que o pedido foi correctamente colocado da fila
• Se for outro (e.g., ERROR_INVALID_USER_BUFFER, ERROR_NOT_ENOUGH_MEMORY) então o
pedido não foi aceite

Recepção de Noticações de IO
Assíncrono
• Existem 4 formas
1. Sinalizar o objecto kernel do dispositivo
2. Sinalizar objectos kernel de evento
3. Utilizar IO alertável
4. Utilizar IO Completion Ports
• A última opção é a mais escalável, flexível e complexa
• Implementação utilizando “IO Completion Ports”
– Invocar CreateIoCompletionPort(...) para
• Criar a porta
• Associar o dispositivo à porta
– Criar uma thread que espera pelas notificações, utilizando
GetQueuedCompletionStatus(…) para
• Pôr a thread a “dormir”
• Acordar a LIFO thread quando uma notificação chegar (ou ocorrer o timeout)
– Processar os dados do pedido concluído, utilizando
• O número de bytes transferidos
• A chave que identifica o dispositivo que completou o pedido
• O apontador que é devolvido para a respectiva estrutura OVERLAPPED
• Mais info na secção “Receiving Completed IO Request Notifications” do MSDN
(http://msdn.microsoft.com/en-us/library/cc500404.aspx)
Identificação dos pedidos
completados no EchoApp.cpp
• Na realização de um pedido de IO (invocação de ReadFile, WriteFile,
...) é fornecido um apontador para uma estrutura OVERLAPPED
• Quando o pedido é concluído a função GetQueuedCompletionStatus(…)
devolve no seu 4º parâmetro esse mesmo apontador
• Cabe ao programador estabelecer a relação entre a notificação e o
(conteúdo do) pedido, através da estrutura OVERLAPPED que é única
e comum aos dois
• O exemplo EchoApp.cpp
– utiliza um buffer de mensagens de IO (lidas/escritas) e um buffer de estruturas
OVERLAPPED com o mesmo tamanho
– a estrutura OVERLAPPED com o índice i corresponde à mensagem com o
mesmo índice
– o indice da mensagem que foi lida/escrita é igual à subtracção do apontador
para a estrutura OVERLAPPED do pedido completado e o apontador para o
inicio do buffer de estruturas OVERLAPPED *
• Uma alternativa é utilizar o mecanismo de herança da programação OO ...
(*) A diferença (subtracção) entre dois apontadores para o tipo OVERLAPPED, vem em unidades de
sizeof(OVERLAPPED) e não em bytes.

You might also like