[Haskell-cafe] Question about concurrency, threads and GC

Paul Graphov graphov at gmail.com
Fri Mar 2 17:19:56 CET 2012

Hello Cafe!

I am trying to implement networked application in Haskell. It should accept many
client connections and support bidirectional conversation, that is not
just loop with
Request -> Response function but also sending notifications to clients etc.

NB: I came from C++ background and used to explicit asynchonous operations
and pools of OS threads. (Boost.Asio + Boost.Thread)

There seem to be lots of goodies around (green threads, STM). The
problem is that
I cannot figure out how to design such applications. First of all now
I have to start
some threads for each client. Client state and behaviour may change depending on
data that comes from it or other clients. So it seems that I have to
start at least three
threads: one that reads data from socket, one that sends queued messages to
the socket and one that represents clients main behaviour loop. The
last one will
supposedly read from some STM sources, one of them being TChan/TMVar filled
by thread that reads socket. Here I get stuck: how to manage that threads?

I tried to search STM examples at hackage and the most interesting
packages were:

1) combinatorrent - quite complex application, but it seem to be
highly Erlang-inspired,
so I am not sure that it is the simplest way of doing thing.

2) network-connection package - it is a library that wraps socket and
uses STM internally
but exposes almost the same interface with blocking operations. Thread
management is
quite explicit there. But this package is marked obsolete.

I wondered if one can rely upon garbage collector to reap dead threads
when using STM?
Or is it too error prone (accidental references to STM object that
prevent it from being
collected) and unpredictable?

I have read this post:

It shows that relying upon handling BlockedIndefinitelyOn* exceptions
is a bad idea but
is it OK just to rely upon that blocked forever thread will die and
not to kill it explicitly?

And also if it is really reliable, what are exact rules when some
object goes out of scope
and becomes collectable? For example in blog post mentioned above in
"main1" example
"lock" variable is accessible until the end of do-block, i.e. if I add
"takeMVar lock" line to
its end, it will compile. But it is not used actually. Is it
guaranteed that explicit performGC
will reap it?

Possibly the best answer would be just pointing me to some recent
examples of concurrent
network applications.


More information about the Haskell-Cafe mailing list