Pregunta

Tengo dos MVAR (bueno, un MVAR y un Chan). Necesito sacar las cosas del chan y procesarlas hasta que el otro MVAR ya no esté vacío. Mi solución ideal sería algo como el Unix select Funciona donde paso en una lista de MVAR (presumiblemente vacíos) y los bloques de hilo hasta que uno de ellos esté lleno, luego devuelve el MVAR completo. Intenta que, como yo, no puedo pensar en ninguna manera de hacer esto más allá de las encuestas repetidamente a cada MVAR con IsEmptyMvar hasta que me ponga falso. Esto parece ineficiente.

Un pensamiento diferente era usar Throwto, pero interrumpe lo que está sucediendo en el hilo y necesito completar el procesamiento de un trabajo del Chan de manera atómica.

Un pensamiento final, ya que estoy escribiendo es crear un nuevo Forkio para cada MVAR que intenta leer su MVAR y luego llenar un MVAR recién creado con su propia instancia. El hilo original puede bloquear en ese MVAR. ¿Los hilos de Haskell son lo suficientemente baratos como para ir a correr?

¿Fue útil?

Solución

Los hilos de Haskell son muy baratos, por lo que podría resolverlo de esa manera, pero parece que STM sería mejor para su problema. Con stm puedes hacer

do var <- atomically (takeTMVar a `orElse` takeTMVar b)
   ... do stuff with var

Por el comportamiento de retry y orElse, este código intenta obtener a, entonces, si eso falla, consigue b. Si ambos fallan, bloquea hasta que cualquiera de ellos se actualice e intente nuevamente.

Incluso podría usar esto para hacer su propia versión rudimentaria de select:

select :: [TMVar a] -> STM a
select = foldr1 orElse . map takeTMVar

Otros consejos

¿Qué tal usar versiones STM, TChan y TVar, con el retry y orElse ¿comportamiento?

Implementar Select es una de las buenas capacidades de STM. De "Transacciones de memoria compuesta":

Más allá de esto, también proporcionamos Orelse, lo que les permite ser compuestos como alternativas, de modo que el segundo se ejecute si los primeros requisitos (Sección 3.4). Esta habilidad permite que los hilos esperen muchas cosas a la vez, como la llamada del sistema Select Unix, excepto que Orelse compone bien, mientras que Select no lo hace.


Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top