1

My question is how does Haskell interact with the system. For example, how does IO happen?

I'm not interested in the IO monad. Or how to make Haskell print a string or read a file. I'm interested in the layer (if that's how it works) between Haskell and the underlying operating system. How does Haskell itself (not me) print anything to the console? How does it interact with the OS?

For example, in Python I can execute any system command. I can just make it do echo message.

Where this really becomes important is understanding how sockets work, and how I can make sure that my program gets interrupted when I get a new connection.

In python, one way to do it is using epoll which is part of the OS (and I believe just takes over control of the python process).

EDIT: as @Daniel Wagner has suggested let me make this question more specific. I am not struggling with a problem currently, I'm just theoretically curious. So let me ask you this: How does Haskell handle interrupts produced by sockets on Linux?

EDIT: And to make it easier to understand what I'm looking for in an answer: - Does Haskell stop dead in it's tracks when it gets an interrupt? - Is there any guarantees that I can answer a new connection before I can finish processing the old? - How does it get an interrupt?

Anton
  • 2,282
  • 26
  • 43
  • At some point, the Haskell standard I/O library has some bindings to native code, presumably to standard C I/O routines. – The Paramagnetic Croissant May 20 '14 at 19:01
  • Your question is a bit vague. (Operating systems are big!) Is it, "How do I use sockets?"? Or maybe it is, "How do I spawn another process running a particular command?"? If neither, what is the actual problem you are up against right now? What do you need to do that you don't know how to do? – Daniel Wagner May 20 '14 at 19:22

1 Answers1

4

Haskell doesn't specify. As implemented by GHC, there is an IO manager which I believe uses epoll in the background. All of that is hidden behind a layer of abstraction, though, so you should not need to worry about it -- just spawn some threads and let them block on whatever socket you want to read. See also, "How can I watch multiple files/socket to become readable/writable in Haskell?".

Edit to address your second question: No, the runtime should not stop cold on blocking calls (neither the threaded nor the non-threaded runtime). Blocked threads are stored away and the runtime switches to a thread that's ready to execute, just like you would expect. Note that you must use the GHC-provided calls for this to be true--manually using the FFI yourself can completely block the non-threaded runtime. More details on that are summarized in this blog post of mine (skip the gtk-specific "Best practice" and "The guts" sections).

Community
  • 1
  • 1
Daniel Wagner
  • 145,880
  • 9
  • 220
  • 380
  • I'm not sure I completely understand the second part of the answer. Say I have a machine with just one CPU core. I received a packet (1) on the socket and started working away at it. While I'm working on packet (1), another packet (2) comes in. Say it is crucial to my application to handle the packet (2) first. Can I stop everything, and work on packet (2) before I continue working on packet (1)? – Anton May 20 '14 at 19:40
  • 2
    @Andrey How many cores you have isn't really relevant here, since even on a single core modern OS's are perfectly capable of providing the illusion of concurrency if you ask for several OS threads. GHC does this when you compile a program with the threaded runtime. If you want a priority scheme between your threads, you can of course do that, though you'll need to code it up. It is up to you how your threads communicate that, though GHC offers many primitives -- asynchronous exceptions, `STM`, and the more traditional-style `MVar` all come to mind. – Daniel Wagner May 20 '14 at 19:43