in reply to Things you need to know before programming Perl ithreads

Good information, one nitpick.

As you say, Perl 6 uses continuations, and with continuations you can implement threading.

However the threading model that you get is a cooperative multi-tasking model in one process. Which means that you don't get the ability to keep running other threads when one thread does a blocking operation (like a long-running database call), and you again don't get the ability to ever take advantage of multiple CPUs.

But I know that elian is fully aware of both points, and would be astonished if he did not make the OS threading model available to Parrot in some fairly sane fashion.

  • Comment on Re: Things you need to know before programming Perl ithreads

Replies are listed 'Best First'.
Re: Re: Things you need to know before programming Perl ithreads
by ambrus (Abbot) on Feb 03, 2004 at 15:13 UTC

    I think you can do these thing well with continuations. It would work like this. Instead of calling a blocking operation (like read or listen), you call the same in non-blocking mode and a yeald to the next thread repeatedly, until the non-blocking call succeeds. This can be implemented at any level: either Parrot could do it, or a threads library written in Parrot and using continuations, or your program.

    For some operations it might be a problem that a non-blocking operation is unsupported by the OS. But there's an other problem unrelated with Perl: in some cases you cannot just use nonblocking syscalls, you need blocking calls (maybe in an other OS thread) to simulate a bckground operation. An example for this is opening a unix fifo. Opening either end of a fifo normally blocks until the other end gets opened. If both processed try to open a fifo with O_NONBLOCK repeatedly, the operation will never succeed (or only by chance after a long time, I don't know). Is this clear?

    IMO, to solve this problem we'd need some kind of background system calls in the OS that can be started, then checked if it's finished nonblockingly, (or cancelled, or requested that a signal be sent when finished, but these are not quite important). We'd also need a new select syscall that can wait for multiple background syscalls. I would like an OS where all syscalls (except for the most trivial ones like getpid and time) can be started in any of these four modes: blocking, non-blocking, background, and signal-sending.

    Some sub-cases are supported in linux too, but not a general mechanism I imagined here. For example, linux has read and write that runs in the background (asynchronous io), and can send signals when a filedes is ready for io, but this is not extended for other operations like opening a fifo.

      What you say is largely true, but I think misses my points.

      Addressing them out of order, the second point that I made is that cooperative multi-threading doesn't get you the ability to take advantage of multiple CPUs. (Or even multiple virtual CPUs, see Intel's hyperthreading.) That remains true.

      The first point was that any blocking call anywhere blocks the whole program. Yes, there are strategies to avoid making blocking calls. However those strategies might not work in every case, and depend on everyone's cooperation. Even if a strategy can work, unless it works on every OS of interest, Parrot will have to implement the blocking forms. Furthermore in the real world, you have to accept that some extension authors will slip blocking calls in.

      Therefore even though cooperative multi-tasking can work smoothly in theory, in practice it doesn't.

      This claim isn't just cynicism on my part. Historically cooperative multi-tasking has been the first kind of multi-tasking that people reach for. After all it has lots of advantages. It is simple. You can trivially avoid lots of nasty synchronization bugs. In theory it can work wonders. But again and again experience showed that people don't all cooperate, and people have wound up biting the bullet and accepting pre-emptive multi-tasking.