Soket giriş / çıkışlarını verimli bir şekilde yapmak, kqueue, epoll, IO tamamlama portları ve benzerleri ile çözüldü. Eşzamansız dosya G / Ç yapmak bir nevi geç gelen bir durumdur (pencerelerin örtüşen G / Ç ve posix AIO için solaris erken desteği dışında).
Soket G / Ç yapmak istiyorsanız, yukarıdaki mekanizmalardan birini kullanmanız muhtemelen daha iyidir.
Bu nedenle, AIO'nun temel amacı, eşzamansız disk G / Ç sorununu çözmektir. Bu, büyük olasılıkla Mac OS X'in soketleri değil, yalnızca AIO'yu desteklemesinin nedenidir (çünkü kqueue bunu zaten çok daha iyi yapar).
Yazma işlemleri genellikle çekirdek tarafından önbelleğe alınır ve daha sonra temizlenir. Örneğin, sürücünün okuma kafası bloğun yazılacağı yerden geçerken.
Bununla birlikte, okuma işlemleri için, çekirdeğin okumalarınızı önceliklendirmesini ve sıralamasını istiyorsanız, AIO gerçekten tek seçenektir. İşte neden kernal (teorik olarak) bunu herhangi bir kullanıcı seviyesindeki uygulamadan daha iyi yapabilir:
- Çekirdek, yalnızca uygulama disk işlerinizi değil, tüm disk G / Ç'lerini görür ve bunları küresel düzeyde sipariş edebilir
- Çekirdek (olabilir) disk okuma kafasının nerede olduğunu bilebilir ve kafayı en kısa mesafeye taşımak için kendisine ilettiğiniz okuma işlerini en uygun sırada seçebilir
- Çekirdek, okuma işlemlerinizi daha da optimize etmek için yerel komut kuyruğundan yararlanabilir.
- Lio_listio () kullanarak sistem çağrısı başına readv () ile olduğundan daha fazla okuma işlemi gerçekleştirebilirsiniz, özellikle de okumalarınız (mantıksal olarak) bitişik değilse, sistem çağrısı ek yükünden küçük bir miktar tasarruf edebilirsiniz.
- Bir okuma veya yazma çağrısını engellemek için fazladan bir iş parçacığına ihtiyacınız olmadığı için programınız AIO ile biraz daha basit olabilir.
Bununla birlikte, posix AIO'nun oldukça garip bir arayüzü var, örneğin:
- Olay geri aramalarının tek etkili ve iyi desteklenen yolu sinyaller yoluyladır, bu da işlem-global sinyal ad alanından sinyal numaralarının kullanılması anlamına geldiği için bir kitaplıkta kullanılmasını zorlaştırır. İşletim sisteminiz gerçek zamanlı sinyalleri desteklemiyorsa, bu aynı zamanda hangisinin gerçekten bittiğini bulmak için tüm bekleyen isteklerinizi gözden geçirmeniz gerektiği anlamına gelir (bu, örneğin Linux değil, Mac OS X için geçerlidir). Çok iş parçacıklı bir ortamda sinyalleri yakalamak da bazı zor kısıtlamalara neden olur. Tipik olarak sinyal işleyicinin içindeki olaya tepki veremezsiniz, ancak bir sinyal yükseltmeniz, bir boruya yazmanız veya signalfd () (linux üzerinde) kullanmanız gerekir.
- lio_suspend (), select () ile aynı sorunlara sahiptir, iş sayısıyla pek iyi ölçeklenmez.
- lio_listio (), uygulandığı haliyle, geçebileceğiniz oldukça sınırlı sayıda işe sahiptir ve bu sınırı taşınabilir bir şekilde bulmak önemsiz değildir. Başarısız olabilecek sysconf (_SC_AIO_LISTIO_MAX) 'ı çağırmanız gerekir, bu durumda zorunlu olarak tanımlanmayan AIO_LISTIO_MAX tanımlamasını kullanabilirsiniz, ancak daha sonra destekleneceği garantili olarak tanımlanan 2'yi kullanabilirsiniz.
Posix AIO kullanan gerçek dünya uygulamasına gelince, destek sunarken bir performans ölçümü de yayınlayan lighttpd'ye (lighty) göz atabilirsiniz .
Çoğu posix platformu şimdiye kadar posix AIO'yu desteklemektedir (Linux, BSD, Solaris, AIX, tru64). Windows, örtüşen dosya G / Ç'si aracılığıyla bunu destekler. Anladığım kadarıyla yalnızca Solaris, Windows ve Linux eşzamansız'ı gerçekten destekliyor. dosya G / Ç'sini sürücüye kadar tamamlarken, diğer işletim sistemleri asenkronu taklit eder. Çekirdek iş parçacıklı G / Ç. Linux istisna olarak, glibc'deki posix AIO uygulaması, kullanıcı seviyesi iş parçacıklarıyla eşzamansız işlemleri taklit ederken, yerel eşzamansız G / Ç arabirimi (io_submit () vb.), Sürücünün desteklediğini varsayarsak, sürücüye kadar tamamen eşzamansızdır. .
İşletim sistemleri arasında herhangi bir fd için posix AIO'yu desteklememenin, ancak bunu normal dosyalarla kısıtlamanın oldukça yaygın olduğuna inanıyorum.