[Haskell] select(2) or poll(2)-like function?

Ertugrul Soeylemez es at ertes.de
Mon Apr 18 17:54:39 CEST 2011


Mike Meyer <mwm at mired.org> wrote:

> > You also don't need Emacs/Vim, if all you want is to write a simple
> > plain text file.  There is nothing wrong with concurrency, because
> > you are confusing the high level model with the low level
> > implementation.  Concurrency is nothing but a design pattern, and
> > GHC shows that a high level design pattern can be mapped to
> > efficient low level code.
>
> Possibly true. The question is - can it be mapped to a design that's
> as robust and scalable as the ones I'm used to working on?

Well, my Haskell programs run for weeks without problems and can handle
a lot of load easily.


> > In Haskell you should not use explicit, manual OS threading/forking
> > for the same reason you shouldn't write machine code manually.
>
> That's a good thing - providing it doesn't compromise robustness and
> scalability.

Well, any implementation of threading, which compromises robustness or
scalability can be considered broken, and Haskell developers try hard
not to deliver broken packages.  After all, Haskell is all about safety.

Of course, Haskell's RTS is not perfect, but comparing costs will show
that using the RTS is cheaper than writing your own hand-optimized
scheduler.


> > Perhaps Haskell is the wrong language for you.  How about
> > programming in C/C++?  I think you want more control over low level
> > resources than Haskell gives you.  But I suggest having a closer
> > look at concurrency.
>
> Personally, I don't want to have to worry about low-level resources,
> or even concurrency. Having to do so feels to much like having to
> explicitly allocate and free memory, or worry about register
> allocations. But if I have to do those things to get robustness and
> scalability until the languages start being able to deal with it, then
> I need the RTS to get out of the way and let me do my job.

Then again, Haskell is the wrong language.  Don't expect any explicit OS
threading builtin any time soon, if ever.  You have to trust the
compiler and RTS to generate efficient handle/thread handling just as
well as you would have to trust a C compiler to generate efficient
machine code.

And reinventing the wheel is certainly a step away from robustness.
Since most Haskell programmers are using GHC, it follows naturally that
most Haskell developers rely on its RTS.  If it were as badly broken as
you seem to believe it is, then people would not use it.


> If I'm using a value that needs protection from concurrent access
> without providing that protection, I want the system give me an
> error. At run-time is acceptable, but compile time is better. I want
> the system to make sure the concurrent protection mechanisms work
> properly - no deadlocks, no stuck process, etc - without my having to
> do anything but indicate which values need such protection.

Use concurrency with a lockfree communication abstraction like STM.  A
concurrency system is only a proper concurrency system, if you don't
have to care about locking.  Of course checking for deadlocks is
undecidable in general, but GHC is pretty good at finding deadlocked
threads and throws an exception, when it does.


> > When writing concurrent code you don't care about how the RTS maps
> > it to processes and threads.  GHC chose threads, probably because
> > they are faster to create/kill and consume less memory.  But this is
> > an implementation detail the Haskell developer should not have to
> > worry about.
>
> So - what happens when a thread fails for some reason? I'm used to
> dealing with systems that run 7x24 for weeks or even months on
> end. Hardware hiccups, network failures, bogus input, hung clients,
> etc. are all just facts of life. I need the system to keep running
> properly in the face of all those, and I need them to disrupt the
> world as little as possible.

If the hardware goes bad, there isn't much you can do.  But all other
scenarios are handled well.  You will want to write exception handlers.


> Given that the RTS has taken control over this stuff, I sort of expect
> it to take care of noticing a dead process and restarting it as
> well. All of which is fine by me.

The RTS is not responsible for reawakening, only for noticing death.
Note that the RTS is not a server framework.  You can take notice of the
death of a thread and restart it yourself.


> > In other words:  Robustness and scalability should not be your
> > business in Haskell.  You should concentrate on understanding and
> > using the concurrency concept well.  And just to encourage you:  I
> > write productive concurrent servers in Haskell, which scale very
> > well and probably better than an equivalent C implementation would.
> > Reason:  A Haskell thread is not mapped to an operating system
> > thread (unless you used forkOS).  When it is advantageous, the RTS
> > can well decide to let another OS thread continue a running Haskell
> > thread.  That way the active OS threads are always utilized as
> > efficiently as possible.  It would be a pain to get something like
> > that with explicit threading and even more, when using processes.
>
> Well, *someone* has to worry about robustness and scalability. Users
> notice when their two minute system builds start taking four minutes
> (and will be at my door wanting me to fix it) because something didn't
> scale fast enough, or have to be run more than once because a failing
> component build wasn't restarted properly. I'm willing to believe that
> haskell lets you write more scalable code than C, but C's tools for
> handling concurrency suck, so that should be true in any language
> where someone actually thought about dealing with concurrency beyond
> locks and protected methods. The problem is, the only language I've
> found where that's true that *also* has reasonable tools to deal with
> scaling beyond a single system is Eiffel (which apparently abstracts
> things even further than haskell - details like how concurrency is
> achieved or how many concurrent operations you can have are configured
> when you start an application, *not* when writing it). Unfortunately,
> Eiffel has other problems that make it undesirable.

I can't make a comparison, because I don't know Eiffel.  I can only say
that for me personally Haskell's concurrency system is better than
anything I have seen before, including Erlang, which has a very similar
concept, but gives you some language constructs for concurrency, while
in Haskell it is done on a pure library level.


> > That's why the RTS lets you choose the number of OS threads only
> > instead of giving you low level control over the threads.  It spawns
> > as many threads as you ask it to spawn and manages them with its own
> > strategy.  The only way to manipulate this strategy is by deciding
> > whether a particular Haskell thread is bound (forkOS) or not
> > (forkIO).
>
> Does the programmer have to worry about such trivia as the number of
> threads to use?

No, the programmer doesn't and in fact can't (right now).  The user
chooses the number of threads via command line options.


Greets,
Ertugrul


-- 
nightmare = unsafePerformIO (getWrongWife >>= sex)
http://ertes.de/





More information about the Haskell mailing list