FWIW, threads based on an event backend are a solved problem in Perl. The Coro library is what EM is trying to be; they should really take a look. ("Oh but it's PERL!!!!" Yeah, and it actually works.)
FWIW, threads based on an event backend are a solved problem in Perl. The Coro library is what EM is trying to be; they should really take a look. ("Oh but it's PERL!!!!" Yeah, and it actually works.)
The way the Coro author implements Perl threads, by the way, sounds similar to how MacRuby and Rubinius are attempting to remove the GIL in ruby by copying interpreter state so that multiple OS threads can run simultaneously.
edit: after reading further, it turns out these threads are cooperative in that only one can run at a time. Also, it looks like they act more like Ruby fibers in that one must give up control explicitly or make a blocking call that implicitly gives up control. I'd rather the core scheduler be able to preempt threads directly. What if one of the threads takes a long time or ends up in an infinite loop?
"This module collection manages continuations in general, most often in the form of cooperative threads (also called coros, or simply "coro" in the documentation). They are similar to kernel threads but don't (in general) run in parallel at the same time even on SMP machines"
Usually people dismiss Coro because they want to take advantage of multiple cores without running multiple processes. But the reality is that you'll see a maximum 8x speedup if you run 8 OS threads, but if you rewrite your critical section in Haskell, you'll see a 50x speedup. So really , Coros are exactly the right abstraction for "scripting languages". IO performance is great, and expressiveness is great. Speed can be gained in other ways.
The one that a lot of people have gotten excited about recently is Node.js and that uses threads for file I/O (libeio).
You might look into a continuation-based framework. With continuations, you can do purely event-driven IO written in a direct style: the framework can grab the "callback" itself by snagging the continuation of its slow IO functions.
You still run into the same problems with blocking (non-IO, or non-framework) code taking up more than its fair share of time, however.
It works best in Thin (EventMachine) or Rainbows! (Fibers).
If you are doing I/O you should use NeverBlock (http://www.espace.com.eg/neverblock/) they've even implemented a MySQL driver, the best part is they're 'drop-in' so you don't have to learn a new API, they just hide the async calls from you.
Fibers I think are closer to Erlang style than the event loop, and much more straight forward to program.
Without defining thread, your question is pretty close to meaningless.
foo();
bar();
instead of: foo( cb => sub { bar() } );
Behind the scenes, it's basically the same thing. It's cooperative so your code does not get preempted where you don't want it to be; the locking is implicit.But you can switch to preemption and explicit locking if you desire. At that point, IMO, it's time to ditch Perl / Python / Ruby and use a language with a sane STM implementation, because locks suck.