Pergunta

Estou trabalhando em meu pequeno framework C ++ e tenho uma classe de arquivo que também deve suportar leitura e escrita assíncrona. A única solução além de usar o arquivo síncrono e / ou dentro de alguns threads de trabalho que encontrei é aio. De qualquer forma, eu estava olhando em volta e li em algum lugar, que no Linux, aio nem mesmo está implementado no kernel, mas sim com threads de usuário. O mesmo vale para OSX? Outra preocupação é a funcionalidade de callbacks do aio, que tem que gerar um thread extra para cada callback, já que você não pode atribuir um determinado thread ou threadpool para cuidar disso (sinais não são uma opção para mim). Então, aqui estão as perguntas resultantes disso:

  • O aio está implementado no kernel do osx e, portanto, é provavelmente melhor do que minha própria implementação em thread?

  • O sistema de retorno de chamada - criando um thread para cada retorno de chamada - pode se tornar um gargalo na prática?

  • Se não vale a pena usar o aio no osx, há alguma outra alternativa no unix? no cacau? em carbono?

  • Ou devo simplesmente emular E / S assíncrona com meu próprio threadpool?

Qual é a sua experiência no assunto?

Foi útil?

Solução

Você pode ver exatamente como AIO é implementado no OSX direito aqui .

A implementação usa threads de kernel, uma fila de jobs que cada thread abre e executa de maneira bloqueadora em uma fila de prioridade com base na prioridade de cada solicitação (pelo menos é o que parece à primeira vista).

Você pode configurar o número de threads e o tamanho da fila com sysctl. Para ver essas opções e os valores padrão, execute sysctl -a | grep aio

kern.aiomax = 90
kern.aioprocmax = 16
kern.aiothreads = 4

Na minha experiência, para que faça sentido usar AIO, esses limites precisam ser muito mais altos.

Quanto aos retornos de chamada em threads, não acredito que o Mac OS X suporte isso. Ele só faz notificações de conclusão por meio de sinais (ver fonte).

Você provavelmente poderia fazer um trabalho tão bom em seu próprio pool de threads. Uma coisa que você poderia fazer melhor do que a implementação atual do darwin é classificar seus trabalhos de leitura por localização física no disco (consulte fcntl e F_LOG2PHYS), o que pode até lhe dar uma vantagem.

Outras dicas

@Moka : Desculpe dizer que você está errado na implementação do linux, a partir do kernel 2.6 há uma implementação do kernel do AIO, que vem em libaio (libaio.h)

A implementação que não usa threads de Kernel, mas em vez disso usa threads de usuário é POSIX.1 AIO, e faz isso dessa forma para torná-la mais portátil, já que nem todos os sistemas operacionais baseados em Unix suportam eventos de conclusão no nível do Kernel.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top