Suggestiong for inter-thread communication

Hi all, I am in the process of writing a Haskell program consisting of two threads, one for performing a calculation and one for an Ncurses UI (haskell-ncurses). The calculation thread needs to feed a stream of numbers back to the UI thread (about 1 value per second) and the UI needs to take input from the user and will pass parameter changes to the calculation thread using an IORef and atomicModifyIORef. However, I'm not sure how to hande the UI thread. The UI thread would normally wait for Ncurses input using getEvent, but I need advice on how to the the data from the calculation thread. Any advice or things to try? Cheers, Erik -- ---------------------------------------------------------------------- Erik de Castro Lopo http://www.mega-nerd.com/

Do you need advice on what? I didn't understand your last phrase.
Em 26/01/2013 06:25, "Erik de Castro Lopo"
Hi all,
I am in the process of writing a Haskell program consisting of two threads, one for performing a calculation and one for an Ncurses UI (haskell-ncurses).
The calculation thread needs to feed a stream of numbers back to the UI thread (about 1 value per second) and the UI needs to take input from the user and will pass parameter changes to the calculation thread using an IORef and atomicModifyIORef.
However, I'm not sure how to hande the UI thread. The UI thread would normally wait for Ncurses input using getEvent, but I need advice on how to the the data from the calculation thread.
Any advice or things to try?
Cheers, Erik -- ---------------------------------------------------------------------- Erik de Castro Lopo http://www.mega-nerd.com/
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe

On Sat, Jan 26, 2013 at 07:46:04AM -0200, Thiago Negri wrote:
Do you need advice on what? I didn't understand your last phrase.
IIUC, it has to do which how to interrupt a blocking call to ncurses event handling, from another thread (the calculation thread) to let the UI thread refresh the UI with something to display (the calculation). I've been confronted with the same problem in the past, and i haven't found a satisfactory solution with ncurses. Erik, I think the only way to do that with ncurses, is to wrap the ncurses getevent with a select loop on the terminal fd and an arbitrary fd to be able to "ping" the select loop for arbitrary processing. You can also replace the arbitrary fd with a SIGALARM to yourself which i believe would interrupt select too. I don't think there's any solution that integrate nicely with the haskell way, but i'ld be happy to be wrong on this. In my case, i switched to Vty which solved this problem, by allowing to send arbitrary strongly-typed event to widgets. -- Vincent

Thiago Negri wrote:
Do you need advice on what? I didn't understand your last phrase.
Well I have data from two sources, stdin and the calculation thread. If I was doing this in C, I'd probably use a pipe for the calculation data and then do select on the two file descriptors. There is a select package: http://hackage.haskell.org/package/select but I was wondering if there was a more idiomatic Haskell way of dealing with inputs from more than one source. Erik -- ---------------------------------------------------------------------- Erik de Castro Lopo http://www.mega-nerd.com/

Erik de Castro Lopo
Do you need advice on what? I didn't understand your last phrase.
Well I have data from two sources, stdin and the calculation thread. If I was doing this in C, I'd probably use a pipe for the calculation data and then do select on the two file descriptors.
There is a select package:
http://hackage.haskell.org/package/select
but I was wondering if there was a more idiomatic Haskell way of dealing with inputs from more than one source.
Of course. Threads communicate through MVars, Chans and other abstractions. If you have more complicated scenarios like one thread communicating with multiple other threads in a selective fashion you may also be interested in software transactional memory (STM). If you are using separate threads to perform calculations, you should make sure that you only pass fully evaluated values. In many cases it suffices to evaluate to WHNF, in which case you can simply write: putMVar var $! x This writes the WHNF of 'x' to the MVar 'var'. If the values you pass around are of more complicated data types with non-strict parts (like (Integer, Integer) instead of just Integer), you can also evaluate to NF: import Control.DeepSeq putMVar var $!! x Another option is go without concurrency entirely. Since this is about parallel calculations, I suppose that your computations are actually pure. Let me give you an example: let xs :: [Integer] xs = map (^1000000) [2..1000] mapM_ print xs To parallelize this you can simply use parallel strategies: import Control.Parallel.Strategies let xs :: [Integer] xs = parMap rseq (^1000000) [2..1000] mapM_ print xs This calculates the list values in parallel and is as simple as replacing "map" by "parMap rseq" or "parMap rdeepseq" (if the elements have non-strict parts like (Integer, Integer) instead of just Integer). Remember that for pure values you can always just say, "please evaluate this in parallel". No need at all to mess around with threads. Greets, Ertugrul -- Not to be or to be and (not to be or to be and (not to be or to be and (not to be or to be and ... that is the list monad.

On 13-01-26 05:28 AM, Erik de Castro Lopo wrote:
Thiago Negri wrote:
Do you need advice on what? I didn't understand your last phrase.
Well I have data from two sources, stdin and the calculation thread. If I was doing this in C, I'd probably use a pipe for the calculation data and then do select on the two file descriptors.
There is a select package:
http://hackage.haskell.org/package/select
but I was wondering if there was a more idiomatic Haskell way of dealing with inputs from more than one source.
There are list arrows, and also coroutines in many guises including pipes, conduits, and iteratees. These are all co-operative concurrency, however, and I can't tell if your problem requires pre-emptive threads.

Hi Erik,
there seem to be several options. Tie simplest one is that you'll call
getEvent with some reasonable timeout in a loop and check some
communication channel an update from the calculation thread.
Probably the correct way how to handle it involves three threads:
(1) The computation thread writes its updates to a channel of type Either
Event ComputationUpdate using Right.
(2) Another thread calls getEvent repeatedly and writes received events to
the channel using Left.
(3) A consuming thread (the one for Ncurses UI) consumes the channel and
reacts both to computation updates and Ncurses events.
However, I'm not sure if Ncurses doesn't mind calling getEvent from a
different thread than the one that updates UI.
For the communication channel, I'd probably use TQueue (or TBQueue, if
there is a risk of writing values too fast).
Best regards,
Petr Pudlak
2013/1/26 Erik de Castro Lopo
Hi all,
I am in the process of writing a Haskell program consisting of two threads, one for performing a calculation and one for an Ncurses UI (haskell-ncurses).
The calculation thread needs to feed a stream of numbers back to the UI thread (about 1 value per second) and the UI needs to take input from the user and will pass parameter changes to the calculation thread using an IORef and atomicModifyIORef.
However, I'm not sure how to hande the UI thread. The UI thread would normally wait for Ncurses input using getEvent, but I need advice on how to the the data from the calculation thread.
Any advice or things to try?
Cheers, Erik -- ---------------------------------------------------------------------- Erik de Castro Lopo http://www.mega-nerd.com/
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe

On Sat, Jan 26, 2013 at 5:51 AM, Petr P
However, I'm not sure if Ncurses doesn't mind calling getEvent from a different thread than the one that updates UI.
I don't know if the Haskell bindings change this, but at the C level as long as automatic echo to a window is turned off, it should be safe to do reads from one thread and writes from another. -- brandon s allbery kf8nh sine nomine associates allbery.b@gmail.com ballbery@sinenomine.net unix, openafs, kerberos, infrastructure, xmonad http://sinenomine.net

Hi Eric, In a previous project, I chose vty over ncurses: - you can write your own event loop, and hence handle different event sources. - more liberal license (BSD3 versus GPL) Tim On 26/01/13 19:24, Erik de Castro Lopo wrote:
Hi all,
I am in the process of writing a Haskell program consisting of two threads, one for performing a calculation and one for an Ncurses UI (haskell-ncurses).
The calculation thread needs to feed a stream of numbers back to the UI thread (about 1 value per second) and the UI needs to take input from the user and will pass parameter changes to the calculation thread using an IORef and atomicModifyIORef.
However, I'm not sure how to hande the UI thread. The UI thread would normally wait for Ncurses input using getEvent, but I need advice on how to the the data from the calculation thread.
Any advice or things to try?
Cheers, Erik
participants (8)
-
Brandon Allbery
-
Erik de Castro Lopo
-
Ertugrul Söylemez
-
Mario Blažević
-
Petr P
-
Thiago Negri
-
Tim Docker
-
Vincent Hanquez