From: Brian Candler Date: 2004-10-04T17:39:04+09:00 Subject: Re: Thinking about Threaded IO On Mon, Oct 04, 2004 at 07:42:14AM +0900, David G. Andersen wrote: > Ruby's threads seem "generally pretty good" about not blocking > on IO calls _if_ you do them right. An example from a program > I was working on: > > mybuf.sbuf += s.sysread(65536) > vs > mybuf.sbuf += s.sysread(4096) > > The former caused (all of) Ruby to block. The latter > was handled properly. I _assume_, but didn't verify, > that this is because Ruby was doing something like > > select() > read(foo) > > internally Essentially that's right. Was there any reason to use 'sysread' rather than 'read'? I think that mybuf.sbuf += s.read(65536) probably would have worked as you'd expected. > In _general_, you shouldn't have to use nonblocking IO, > but there are likely operations that Ruby can't make internally > nonblocking. DNS lookups are often a pain to perform > asynchronously unless you explicitly use an async > DNS library, for instance. File operations over > NFS can block and are next to impossible to > deal with without either multiple processes or > kernel-level multithreading (particularly metadata > operations like lookup and open). All good points. I'd just add that things like external database libraries (e.g. mysql) tend to block too. I've seen some which don't; the Oracle OCI8 binding for ruby has the ability to be put in a 'nonblocking' mode, but what it actually does is poll for a result after 1ms, 2ms, 4ms, 8ms...etc ! For such applications, separate processes are often essential. For web applications I've had a lot of success with fcgi, where a pool of persistent processes is set up by Apache under mod_fastcgi, and each one only handles a single request at a time. This means you don't have to worry about thread safety as well as blocking. Regards, Brian.