tags:

views:

154

answers:

2

The title may be a bit vague. This is what I mean:

Say I have two ways of getting input to my program. The first is via the keyboard, using the function getLine which blocks until a line is read. The other is, say, via a TChan, where using readTChan chan will also result in a block until a value is present in the channel, whereupon it will be read.

What I want to accomplish is being able to wait for both values, using a single thread and not allowing my CPU to jump to 100%. The moment one of the two values is available, it is fetched and the program resumes. (Say, using Either to notify which of the two values was received.)

Is this possible?

Thank you very much!

+11  A: 

I don't think "using a single thread" makes sense here. You must already be using multiple Haskell threads anyway to write to the TChan. You should use two Haskell threads to do this, and use an MVar or similar to communicate the first result to arrive. For example:

module Main where

import System.IO
import Control.Concurrent
import Control.Concurrent.MVar
import Control.Concurrent.STM
import Control.Concurrent.STM.TChan

main = do
   chan <- newTChanIO
   forkIO (threadTChanWrite chan)
   threadMultiplexedRead chan

threadTChanWrite chan = do
   threadDelay 5000000
   atomically $ writeTChan chan 3

threadMultiplexedRead chan = do
   mvar <- newEmptyMVar
   forkIO (threadKeyboardRead mvar)
   forkIO (threadTChanRead mvar chan)
   v <- readMVar mvar
   print v

threadKeyboardRead mvar = do
   str <- getLine
   putMVar mvar (Right str)

threadTChanRead mvar chan = do
   v <- atomically (readTChan chan)
   putMVar mvar (Left v)

A proper implementation would probably clean up the threads left lying around afterwards, btw.

Ganesh Sittampalam
+6  A: 

I have two ways of getting input to my program

You should be able to use 2 threads, one per input source, which wait on their respective inputs, writing the result to a shared channel or mvar governed by a third thread.

Don Stewart
-1: you ignored how Q asks for single-threaded sol'n.
Charles Stewart
@Charles You're missing the point. It's rather pointless to not use more than one thread, and the guy fails to even say why.
Rayne
He doesn't need to say why, and I don't see how we know that the wish is pointless.
Charles Stewart