es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Forma libre de carrera para iniciar y cancelar de manera asíncrona E/S en otro hilo en Windows.

Antecedentes: En general, si queremos forzar una operación para que se realice de manera asíncrona (para evitar bloquear el hilo principal), el uso de FILE_FLAG_OVERLAPPED no es suficiente, ya que la operación aún puede completarse de manera síncrona.

Entonces, digamos que, para evitar esto, retrasamos la operación a un hilo de trabajo dedicado a la E/S. Esto evita que el hilo principal sea bloqueado.

Ahora, el hilo principal puede usar CancelIoEx(HANDLE, LPOVERLAPPED) para cancelar la operación de E/S iniciada (digamos, a través de ReadFile) por el trabajador.

Sin embargo, para que CancelIoEx tenga éxito, el hilo principal necesita una manera de garantizar que la operación de hecho ha comenzado, de lo contrario no hay nada que cancelar.

La solución obvia aquí es hacer que el hilo de trabajo establezca un evento después de que su llamada a por ejemplo a ReadFile haya terminado, pero eso nos devuelve al problema original: como ReadFile puede bloquear, habremos derrotado todo el propósito de tener un hilo de trabajo en primer lugar, que era asegurarnos que el hilo principal no estuviera bloqueado en la E/S.

¿Cuál es la manera “correcta” de resolver esto? ¿Hay una buena manera de obligar a que una operación de E/S suceda de manera asíncrona y aún así poder solicitar su cancelación posteriormente de manera libre de errores cuando la E/S aún no ha terminado?

Lo único que se me ocurre es establecer un temporizador para llamar periódicamente a CancelIoEx mientras la E/S no haya completado, pero eso parece increíblemente feo. ¿Hay una solución mejor/más robusta?

Tags:  , , ,

Answer

  1. Avatar for davy.ai

    Una solución a este problema es utilizar un Puerto de finalización de E/S. Esto permite que el hilo trabajador inicie la operación de E/S y luego espere las notificaciones de finalización a través del puerto de finalización. El hilo principal puede luego utilizar el puerto de finalización para verificar si la operación ha comenzado y solicitar su cancelación si es necesario.

    La ventaja de este enfoque es que elimina la necesidad de la comprobación periódica o el cancelamiento por parte del hilo principal. El puerto de finalización proporciona una forma más simplificada para que los hilos trabajador y principal se comuniquen sobre el estado de la operación de E/S.

    Otro enfoque es utilizar E/S superpuestas con una función de retroceso. Cuando se inicia una operación de E/S, también se especifica una función de retroceso. Esta función se llama cuando la operación de E/S se completa, lo que permite que el hilo trabajador notifique al hilo principal de la finalización y las solicitudes de cancelación.

    Sin embargo, este enfoque puede no ser tan eficiente como utilizar un Puerto de finalización de E/S, ya que requiere la creación de un nuevo hilo para cada nueva operación de E/S.

    En general, la mejor solución depende de los requisitos específicos de la aplicación y de las compensaciones entre la eficiencia y la complejidad.

Comments are closed.