Domanda

Ho due mvar (beh un mvar e un Chan). Devo tirar fuori le cose dal Chan ed elaborarle fino a quando l'altro Mvar non è più vuoto. La mia soluzione ideale sarebbe qualcosa di simile all'Unix select funzione in cui passo in un elenco di mvar (presumibilmente vuoti) e i blocchi del thread fino a quando uno di essi è pieno, quindi restituisce l'intero mvar. Prova come potrei pensare a nessun modo di farlo al di là del polling ripetutamente di ogni mvar con isemptymvar fino a quando non sarò falso. Questo sembra inefficiente.

Un pensiero diverso era quello di usare ThrowTto, ma interrompe ciò che sta succedendo nel thread e devo completare l'elaborazione di un lavoro dal Chan in modo atomico.

Un ultimo pensiero mentre sto scrivendo è quello di creare un nuovo forkio per ogni MVAR che cerca di leggere il suo MVAR, quindi riempire un MVAR di recente creazione con la propria istanza. Il thread originale può quindi bloccare su quel MVAR. I thread di Haskell sono abbastanza economici da eseguire così tanti?

È stato utile?

Soluzione

I thread di Haskell sono molto economici, quindi potresti risolverlo in questo modo, ma sembra che STM sarebbe più adatto al tuo problema. Con STM puoi fare

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

A causa del comportamento di retry e orElse, questo codice cerca di ottenere a, quindi se questo fallisce, ottieni b. Se entrambi falliscono, blocca fino a quando uno di essi non viene aggiornato e riprova.

Potresti persino usarlo per creare la tua versione rudimentale di select:

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

Altri suggerimenti

Che ne dici di usare le versioni STM, TChan e TVar, con il retry e orElse comportamento?

L'implementazione di Select è una delle belle funzionalità di STM. Da "Transazioni di memoria composibile":

Oltre a ciò, forniamo anche Orelse, che consente loro di essere composti come alternative, in modo che il secondo sia eseguito se il primo tentativo (Sezione 3.4). Questa abilità consente ai thread di attendere molte cose contemporaneamente, come la chiamata di sistema Select UNIX, tranne che Orelse compone bene, mentre Select no.


Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top