linux - sirve - youtube como medio de comunicacion pdf
¿Realmente no hay bloque I/O asíncrono en Linux? (3)
Como se explica en:
http://code.google.com/p/kernel/wiki/AIOUserGuide
y aquí:
http://www.ibm.com/developerworks/library/l-async/
Linux proporciona E / S de bloques asíncronos a nivel de kernel, las API son las siguientes:
aio_read Request an asynchronous read operation
aio_error Check the status of an asynchronous request
aio_return Get the return status of a completed asynchronous request
aio_write Request an asynchronous operation
aio_suspend Suspend the calling process until one or more asynchronous requests have completed (or failed)
aio_cancel Cancel an asynchronous I/O request
lio_listio Initiate a list of I/O operations
Y si pregunta quiénes son los usuarios de estas API, es el núcleo mismo, aquí solo se muestra un pequeño subconjunto:
./drivers/net/tun.c (for network tunnelling):
static ssize_t tun_chr_aio_read(struct kiocb *iocb, const struct iovec *iv,
./drivers/usb/gadget/inode.c:
ep_aio_read(struct kiocb *iocb, const struct iovec *iov,
./net/socket.c (general socket programming):
static ssize_t sock_aio_read(struct kiocb *iocb, const struct iovec *iov,
./mm/filemap.c (mmap of files):
generic_file_aio_read(struct kiocb *iocb, const struct iovec *iov,
./mm/shmem.c:
static ssize_t shmem_file_aio_read(struct kiocb *iocb,
etc.
En el nivel del espacio de usuario, también está la API io_submit (), etc. (de glibc), pero el siguiente artículo ofrece una alternativa al uso de glibc:
http://www.fsl.cs.sunysb.edu/~vass/linux-aio.txt
Implementa directamente la API para funciones como io_setup () como syscall directo (sin pasar por las dependencias de glibc), debe existir una asignación de kernel a través de la misma firma "__NR_io_setup". Al buscar en la fuente del kernel en:
http://lxr.free-electrons.com/source/include/linux/syscalls.h#L474 (la URL es aplicable a la última versión 3.13) recibe la implementación directa de estas API io _ * () en el kernel :
474 asmlinkage long sys_io_setup(unsigned nr_reqs, aio_context_t __user *ctx);
475 asmlinkage long sys_io_destroy(aio_context_t ctx);
476 asmlinkage long sys_io_getevents(aio_context_t ctx_id,
481 asmlinkage long sys_io_submit(aio_context_t, long,
483 asmlinkage long sys_io_cancel(aio_context_t ctx_id, struct iocb __user *iocb,
La última versión de glibc debería hacer innecesario el uso de "syscall ()" para llamar a sys_io_setup (), pero sin la última versión de glibc, siempre puedes hacer que te llames a ti mismo si estás utilizando el último núcleo con estas capacidades de "sys_io_setup () ".
Por supuesto, hay otra opción de espacio de usuario para E / S asíncronas (por ejemplo, ¿usar señales?):
http://personal.denison.edu/~bressoud/cs375-s13/supplements/linux_altIO.pdf
o perhap:
¿Cuál es el estado de POSIX asíncrono de E / S (AIO)?
"io_submit" y los amigos todavía no están disponibles en glibc (consulte las páginas de manual de io_submit), que he verificado en mi Ubuntu 14.04, pero esta API es específica de Linux.
Otros como libuv, libev y libevent también son API asíncronas:
http://nikhilm.github.io/uvbook/filesystem.html#reading-writing-files
http://software.schmorp.de/pkg/libev.html
Todas estas API pretendían ser portátiles en BSD, Linux, MacOSX e incluso Windows.
En términos de rendimiento, no he visto ningún número, pero ¿sospecho que libuv puede ser el más rápido, debido a su peso liviano?
Considere una aplicación que está vinculada a la CPU, pero que también tiene requisitos de E / S de alto rendimiento.
Estoy comparando la E / S de archivos de Linux con Windows, y no puedo ver cómo epoll ayudará en absoluto a un programa de Linux. El kernel me dirá que el descriptor de archivo está "listo para leer", pero todavía tengo que llamar a bloqueo de lectura () para obtener mis datos, y si quiero leer megabytes, está bastante claro que eso se bloqueará.
En Windows, puedo crear un identificador de archivo con el conjunto OVERLAPPED, y luego usar E / S sin bloqueo, y recibir una notificación cuando se complete la E / S, y usar los datos de esa función de finalización. No necesito dedicar tiempo de reloj de pared a nivel de aplicación a la espera de datos, lo que significa que puedo ajustar mi número de subprocesos con precisión a mi número de núcleos y obtener una utilización del CPU 100% eficiente.
Si tengo que emular E / S asíncronas en Linux, entonces tengo que asignar un número de subprocesos para hacer esto, y esos subprocesos pasarán un poco de tiempo haciendo cosas de la CPU, y mucho tiempo bloqueando para E / S, además, habrá una sobrecarga en la mensajería a / desde esos hilos. Por lo tanto, sobrescribiré o subutilizaré mis núcleos de CPU.
Miré mmap () + madvise () (WILLNEED) como un "E / S asíncrono de un hombre pobre", pero aún no llega hasta allí, porque no puedo recibir una notificación cuando está listo. para "adivinar" y si adivino "incorrecto", terminaré bloqueando el acceso a la memoria, esperando que los datos provengan del disco.
Linux parece tener los inicios de E / S asíncrona en io_submit, y parece tener también una implementación POSIO aio en el espacio de usuario, pero ha sido así durante un tiempo, y no conozco a nadie que responda por estos sistemas para críticas , aplicaciones de alto rendimiento.
El modelo de Windows funciona aproximadamente así:
- Emitir una operación asíncrona.
- Vincule la operación asíncrona a un puerto de finalización de E / S particular.
- Espera a que las operaciones se completen en ese puerto
- Cuando la E / S está completa, el hilo que espera en el puerto se desbloquea y devuelve una referencia a la operación de E / S pendiente.
Los pasos 1/2 se hacen típicamente como una sola cosa. Los pasos 3/4 normalmente se realizan con un conjunto de subprocesos de trabajo, no (necesariamente) el mismo subproceso que emite la E / S. Este modelo es algo similar al modelo proporcionado por boost :: asio, excepto que boost :: asio en realidad no le brinda I / O (disco) asíncrono basado en bloques.
La diferencia con epoll en Linux es que en el paso 4, no se ha producido ninguna E / S; eleva el paso 1 después del paso 4, que es "hacia atrás" si ya sabe exactamente lo que necesita.
Habiendo programado una gran cantidad de sistemas operativos integrados, de escritorio y de servidor, puedo decir que este modelo de E / S asíncrono es muy natural para ciertos tipos de programas. También es de muy alto rendimiento y baja sobrecarga. Creo que esta es una de las deficiencias reales restantes del modelo de E / S de Linux, a nivel de API.
La respuesta real, que fue señalada indirectamente por Peter Teoh, se basa en io_setup () y io_submit (). Específicamente, las funciones "aio_" indicadas por Peter son parte de la emulación de nivel de usuario de glibc basada en subprocesos, que no es una implementación eficiente. La respuesta real está en:
io_submit(2)
io_setup(2)
io_cancel(2)
io_destroy(2)
io_getevents(2)
Tenga en cuenta que la página de manual, con fecha 2012-08, dice que esta implementación aún no ha madurado hasta el punto en que pueda reemplazar la emulación de espacio de usuario de glibc:
http://man7.org/linux/man-pages/man7/aio.7.html
esta implementación aún no ha madurado hasta el punto en que la implementación POSIX AIO pueda reimplementarse completamente utilizando las llamadas del sistema del kernel.
Por lo tanto, de acuerdo con la última documentación del kernel que puedo encontrar, Linux aún no tiene un modelo de E / S asíncrono basado en el kernel. Y, si asumo que el modelo documentado es realmente maduro, todavía no admite E / S parcial en el sentido de recv () vs read ().