From: Simon Kitching Date: 2003-09-24T19:06:55+09:00 Subject: Re: Thread safety: Serializing access to ruby interpreter- again On Wed, 2003-09-24 at 21:38, Thomas Sondergaard wrote: > > Socket might work. > > If you say so, I'll give it a try. > > > > Out of curiousity, why does this happen on Windows? Is it not fixable? > > > > Because winsock's select() supports only socket handles. > > Is all ruby IO implemented in terms of select to avoid blocking the process? > Why doesn't select block the process, btw? > > Thomas Well, I'm a newbie to Ruby, but unfortunately old enough to remember writing C code before real threads existed. I'm guessing Ruby threads work in the old "cooperative" manner, as follows: What you would do is replace blocking calls to read operations with calls to functions implemented like this: read_from_socket: for(;;) { check for data available if data is available read data and return it else schedule some other thread to run // aka "yield" } The check for data is done with a NON-BLOCKING select call, ie one that returns immediately even if no data is currently available. In that case, the current "thread" stops running and some other "thread" gets the CPU. Eventually the current "thread" is rescheduled, goes back to the top of the loop, and checks for data again. It was always a pain to code this way, because you had to call these "yielding" versions of standard library calls rather than the real ones, for every library function that might block. However given that languages like Ruby always have "glue" code for calling native operations like read & write, it works quite tidily for them. The disadvantage, of course, is that because all threading is implemented within a single real OS thread, the app can't take advantage of systems which really have multiple CPUs. And thread "pre-emption" is a bit flaky. I am guessing that Windows doesn't provide a way to check a socket for the presence of data without blocking, meaning that this just can't be implemented. Cheers, Simon