Melakukan soket I / O secara efisien telah diselesaikan dengan kqueue, epoll, port penyelesaian IO dan sejenisnya. Melakukan asynchronous file I / O adalah semacam pendatang yang terlambat (selain dari Windows 'overlapped I / O dan solaris early support untuk posix AIO).
Jika Anda ingin melakukan soket I / O, Anda mungkin lebih baik menggunakan salah satu mekanisme di atas.
Oleh karena itu, tujuan utama AIO adalah untuk memecahkan masalah I / O disk asinkron. Ini kemungkinan besar mengapa Mac OS X hanya mendukung AIO untuk file biasa, dan bukan soket (karena kqueue melakukannya dengan jauh lebih baik).
Operasi tulis biasanya di-cache oleh kernel dan dihapus di lain waktu. Misalnya ketika kepala baca drive kebetulan melewati lokasi di mana blok itu akan ditulis.
Namun, untuk operasi baca, jika Anda ingin kernel memprioritaskan dan memesan bacaan Anda, AIO benar-benar satu-satunya pilihan. Inilah mengapa kernal dapat (secara teoritis) melakukannya lebih baik daripada aplikasi level pengguna mana pun:
- Kernel melihat semua disk I / O, bukan hanya pekerjaan disk aplikasi Anda, dan dapat memesannya di tingkat global
- Kernel (mungkin) tahu di mana kepala pembacaan disk berada, dan dapat memilih tugas baca yang Anda sampaikan kepadanya dalam urutan yang optimal, untuk memindahkan kepala ke jarak terpendek
- Kernel dapat memanfaatkan antrian perintah asli untuk lebih mengoptimalkan operasi baca Anda
- Anda mungkin dapat mengeluarkan lebih banyak operasi baca per panggilan sistem menggunakan lio_listio () daripada dengan readv (), terutama jika pembacaan Anda tidak (secara logis) berdekatan, menghemat sedikit overhead system call.
- Program Anda mungkin sedikit lebih sederhana dengan AIO karena Anda tidak memerlukan utas tambahan untuk memblokir panggilan baca atau tulis.
Bisa dikatakan, posix AIO memiliki antarmuka yang cukup canggung, misalnya:
- Satu-satunya cara callback peristiwa yang efisien dan didukung dengan baik adalah melalui sinyal, yang membuatnya sulit digunakan di perpustakaan, karena ini berarti menggunakan nomor sinyal dari ruang nama sinyal global proses. Jika OS Anda tidak mendukung sinyal realtime, itu juga berarti Anda harus mengulang semua permintaan yang belum selesai untuk mencari tahu mana yang benar-benar selesai (ini adalah kasus untuk Mac OS X misalnya, bukan Linux). Menangkap sinyal dalam lingkungan multi-thread juga membuat beberapa pembatasan rumit. Anda biasanya tidak dapat bereaksi terhadap kejadian di dalam penangan sinyal, tetapi Anda harus menaikkan sinyal, menulis ke pipa atau menggunakan signalfd () (di linux).
- lio_suspend () memiliki masalah yang sama seperti select (), tidak diskalakan dengan baik dengan jumlah pekerjaan.
- lio_listio (), seperti yang diterapkan memiliki jumlah pekerjaan yang cukup terbatas yang dapat Anda lewati, dan tidak mudah menemukan batas ini dengan cara portabel. Anda harus memanggil sysconf (_SC_AIO_LISTIO_MAX), yang mungkin gagal, dalam hal ini Anda dapat menggunakan definisi AIO_LISTIO_MAX, yang belum tentu ditentukan, tetapi kemudian Anda dapat menggunakan 2, yang didefinisikan sebagai dijamin akan didukung.
Sedangkan untuk aplikasi dunia nyata menggunakan posix AIO, Anda dapat melihat lighttpd (lighty), yang juga memposting pengukuran kinerja saat memperkenalkan dukungan.
Kebanyakan platform posix mendukung posix AIO sekarang (Linux, BSD, Solaris, AIX, tru64). Windows mendukungnya melalui file I / O yang tumpang tindih. Pemahaman saya adalah bahwa hanya Solaris, Windows dan Linux yang benar-benar mendukung async. file I / O sampai ke driver, sedangkan OS lain meniru async. I / O dengan utas kernel. Linux menjadi pengecualian, implementasi posix AIO-nya di glibc mengemulasi operasi asinkron dengan utas tingkat pengguna, sedangkan antarmuka I / O asinkron aslinya (io_submit () dll.) Benar-benar asinkron sampai ke driver, dengan asumsi driver mendukungnya .
Saya percaya itu cukup umum di antara OS untuk tidak mendukung posix AIO untuk fd apa pun, tetapi membatasinya ke file biasa.