Sincronización y entrada y salida superpuestas
Puede realizar operaciones de E/S sincrónicas o asincrónicas (también denominadas superpuestas) en archivos, canalizaciones con nombre y dispositivos de comunicaciones serie. Las funciones WriteFile, ReadFile, DeviceIoControl, WaitCommEvent, ConnectNamedPipe y TransactNamedPipe se pueden realizar de forma sincrónica o asincrónica. Las funciones ReadFileEx y WriteFileEx solo se pueden realizar de forma asincrónica.
Cuando una función se ejecuta de forma sincrónica, no devuelve hasta que se haya completado la operación. Esto significa que la ejecución del subproceso de llamada se puede bloquear durante un período indefinido mientras espera a que finalice una operación que consume mucho tiempo. Las funciones llamadas para la operación superpuesta pueden devolverse inmediatamente, aunque la operación no se haya completado. Esto permite ejecutar una operación de E/S que consume mucho tiempo en segundo plano mientras el subproceso de llamada es libre de realizar otras tareas. Por ejemplo, un único subproceso puede realizar operaciones de E/S simultáneas en diferentes identificadores, o incluso operaciones simultáneas de lectura y escritura en el mismo identificador.
Para sincronizar su ejecución con la finalización de la operación superpuesta, el subproceso de llamada usa la función GetOverlappedResult , la función GetOverlappedResultEx o una de las funciones de espera para determinar cuándo se ha completado la operación superpuesta. También puede usar la macro HasOverlappedIoCompleted para sondear la finalización.
Para cancelar todas las operaciones de E/S asincrónicas pendientes, use la función CancelIoEx y proporcione una estructura SUPERPUESTA que especifique la solicitud que se va a cancelar. Use la función CancelIo para cancelar las operaciones de E/S asincrónicas pendientes emitidas por el subproceso de llamada para el identificador de archivo especificado.
Las operaciones superpuestas requieren un archivo, una canalización con nombre o un dispositivo de comunicaciones que se creó con la marca FILE_FLAG_OVERLAPPED . Cuando un subproceso llama a una función (como la función ReadFile ) para realizar una operación superpuesta, el subproceso que realiza la llamada debe especificar un puntero a una estructura SUPERPUESTA . (Si este puntero es NULL, el valor devuelto de la función puede indicar incorrectamente que la operación se completó). Todos los miembros de la estructura SUPERPUESTA deben inicializarse en cero a menos que se use un evento para indicar la finalización de una operación de E/S. Si se usa un evento, el miembro hEvent de la estructura SUPERPUESTA especifica un identificador para el objeto de evento asignado. El sistema establece el estado del objeto de evento en sin signo cuando una llamada a la función de E/S vuelve antes de que se haya completado la operación. El sistema establece el estado del objeto de evento que se indica cuando se ha completado la operación. Solo se necesita un evento si habrá más de una operación de E/S pendiente al mismo tiempo. Si no se usa un evento, cada operación de E/S completada indicará el archivo, la canalización con nombre o el dispositivo de comunicaciones.
Cuando se llama a una función para realizar una operación superpuesta, es posible que la operación se complete antes de que la función devuelva. Cuando esto sucede, los resultados se controlan como si la operación se hubiera realizado de forma sincrónica. Sin embargo, si la operación no se completó, el valor devuelto de la función es FALSE y la función GetLastError devuelve ERROR_IO_PENDING.
Un subproceso puede administrar las operaciones superpuestas mediante cualquiera de los dos métodos:
- Use la función GetOverlappedResult o GetOverlappedResultEx para esperar a que se complete la operación superpuesta. Si se usa GetOverlappedResultEx , el subproceso de llamada puede especificar un tiempo de espera para la operación superpuesta o realizar una espera de alerta.
- Especifique un identificador para el objeto de evento de restablecimiento manual de la estructura SUPERPUESTA en una de las funciones de espera y, a continuación, después de que la función de espera vuelva, llame a GetOverlappedResult o GetOverlappedResultEx. La función devuelve los resultados de la operación superpuesta completada y, para las funciones en las que es adecuada dicha información, notifica el número real de bytes transferidos.
Al realizar varias operaciones superpuestas simultáneas en un único subproceso, el subproceso de llamada debe especificar una estructura SUPERPUESTA para cada operación. Cada estructura SUPERPUESTA debe especificar un identificador para un objeto de evento de restablecimiento manual diferente. Para esperar a que se complete cualquiera de las operaciones superpuestas, el subproceso especifica todos los identificadores de eventos de restablecimiento manual como criterios de espera en una de las funciones de espera de varios objetos. El valor devuelto de la función de espera de varios objetos indica qué objeto de evento de restablecimiento manual se señalizó, por lo que el subproceso puede determinar qué operación superpuesta hizo que se completara la operación de espera.
Es más seguro usar un objeto de evento independiente para cada operación superpuesta, en lugar de especificar ningún objeto de evento o reutilizar el mismo objeto de evento para varias operaciones. Si no se especifica ningún objeto de evento en la estructura SUPERPUESTA , el sistema señala el estado del archivo, la canalización con nombre o el dispositivo de comunicaciones cuando se ha completado la operación superpuesta. Por lo tanto, puede especificar estos identificadores como objetos de sincronización en una función de espera, aunque su uso para este propósito puede ser difícil de administrar porque, al realizar operaciones superpuestas simultáneas en el mismo archivo, canalización con nombre o dispositivo de comunicaciones, no hay ninguna manera de saber qué operación provocó que se señale el estado del objeto.
Un subproceso no debe reutilizar un evento con la suposición de que la operación superpuesta del subproceso indicará el evento. Se señala un evento en el mismo subproceso que la operación superpuesta que se está completando. El uso del mismo evento en varios subprocesos puede provocar una condición de carrera en la que el evento se señala correctamente para el subproceso cuya operación se completa primero y prematuramente para otros subprocesos que usan ese evento. A continuación, cuando se completa la siguiente operación superpuesta, el evento se señala de nuevo para todos los subprocesos que usan ese evento, etc. hasta que se completen todas las operaciones superpuestas.
Para obtener ejemplos que ilustran el uso de operaciones superpuestas, rutinas de finalización y la función GetOverlappedResult , consulte Uso de canalizaciones.
Windows Vista, Windows Server 2003 y Windows XP:
Tenga cuidado al reutilizar estructuras SUPERPUESTAS . Si las estructuras SUPERPUESTAs se reutilizan en varios subprocesos y se llama a GetOverlappedResult con el parámetro bWait establecido en TRUE, el subproceso de llamada debe asegurarse de que el evento asociado se señale antes de reutilizar la estructura. Esto se puede lograr mediante la función WaitForSingleObject después de llamar a GetOverlappedResult para forzar que el subproceso espere hasta que se complete la operación. Tenga en cuenta que el objeto de evento debe ser un objeto de evento de restablecimiento manual. Si se usa un objeto de evento autoreset, llamar a GetOverlappedResult con el parámetro bWait establecido en TRUE hace que la función se bloquee indefinidamente. Este comportamiento cambió a partir de Windows 7 y Windows Server 2008 R2 para las aplicaciones que especifican Windows 7 como sistema operativo compatible en el manifiesto de aplicación. Para obtener más información, vea Manifiestos de aplicación.
Temas relacionados