John Goerzen wrote:
On Thu, Mar 01, 2007 at 03:06:22PM +0000, Simon Marlow wrote:
Ok, what happens here is that in the forked process there is only a single
thread, the runtime kills all the other threads (as advertised).
Unfortunately this includes the I/O manager thread, so as soon as you do
some I/O in the forked process, you block.
Could it just revert to the nonthreaded IO model, or is that not within
the scope of what's easily achievable with the threaded RTS?
The non-threaded I/O system just isn't compiled into the threaded RTS at all.
We used to use it in the threaded RTS before we switched to the I/O manager
thread, but as I recall it was a rich source of bugs; the I/O manager thread is
much simpler, being in Haskell.
On a more general note, forkProcess is known to be hairy - simply the fact
that it kills all the other threads in the system in the forked process
means that there's a good supply of means to shoot yourself in the foot,
even accidentally. John - perhaps there's another way to achieve what you
want?
Right. Part of this problem may be one of documentation, and part of it
rests with ghci.
I have no need for threads in this program. And, in fact, as you said,
threads are known to be hazardous when used in conjuntion with fork().
I have no interest in combining the to. The mechanics of signal
propogation, file descriptor closing, etc. all get complicated.
But it seems like there is not much choice with ghci. It appears to be
built with the threaded RTS by default, and uses threads even though I
never try to use threads with it. And there seems to be no way to turn
it off.
The problem is that the choice between -threaded and non-threaded is made at
link-time, so we have to make that choice when we link the GHCi binary.
In fact you should think of the non-threaded RTS as deprecated. It isn't
Haskell'-compliant, for one thing (assuming that Haskell' will probably require
non-blocking foreign calls).
I'm hesitant to actually deprecate it, for a few reasons: the threaded RTS is so
much more complicated, it might have some adverse performance impliciations, and
there are still people who want to run everything in a single OS thread, for
whatever reason. But having multiple variants of the RTS is a maintenance and
testing headache.
Between that and the lack of support for forkProcess in Hugs, this
renders anything that needs to fork and then do I/O as being usable only
in GHC-compiled code. Which is sub-optimal, but livable anyway.
I guess I'm really wondering why you need to fork and do I/O at all. Can you
describe the problem at a higher level?
Also, why does hGetContents not work, but hPutStr does? If the IO
manager is dead, how does some IO still work?
Ah well, only I/O that needs to block uses the I/O manager thread. I/O that
doesn't block just proceeds directly.
Cheers,
Simon
_______________________________________________
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users