Fibers, threads, and processes! Oh, my! Fibers are probably the most interesting part of this, and ruby’s slightly broken threading model. Processes are interesting from the aspect of being able to communicate with external programs.
Fibers are completely 1.9. There’s no such thing as fibers in ruby 1.8. They sound like they’d be some kind of lightweight thread, but are really just a coroutine. I’ve never heard of coroutine stuff before, so this concept is new to me. It allows you to decouple a few things. The books example is having a background fiber running some complex calculation while the main thread does something with the previous result of that calculation. There’s some more on fibers, coroutines, and continuations, but the text doesn’t appear to be very complete on this part. It links to oblivion to get more information on continuations. Doh.
Multithreading. Ruby 1.8’s threading model was implemented entirely within the interpreter. So you only got one thread on the CPU, one core. Not so great. Ruby 1.9 has some marginal improvements so that you can run native threads, but due to the thread model changing it will never really run more than one thread concurrently. So while it can jump between threads quickly, you can’t have a truly multithreaded application in ruby. I’m hoping that ruby 2.0 or maybe 1.9.1 will have updated those libraries that don’t work in this threading model so that true multithreading can happen. Especially for things like Rails, where it could provide a huge performance benefit.
The exsting threading abilities in ruby are pretty potent. You can get the stats, see if it’s alive, join with it, and set the priority of the thread. Threading behaves similar to how it works in other languages. Without the debug flag set, a thread that raises an exception will die, but the others will continue. Which is the way things should happen, but it’s difficult to catch exceptions that way. You can set abort_on_exception to true, and then the vm will abort with a RuntimeError when the thread raises an exception. There is of course a mutex to help with synchronization issues. Finally, there’s also a Queue class for producer/consumer type applications.
Now you get into running multiple processes. The simplest is to just call system(“do some command”) or use backticks `. If you want to have a small conversation with your external process, you’ll need to use IO.popen. You can then talk to it and read from it. You may have to flush the data to the IO object. Nothing terribly new to people that have worked with external processes before. Ruby supports a fork(2) type invocation by passing a single minus sign to IO.popen(“-“,”w+”). Ruby will then fork off another interpreter, the parent will get back the IO object, and the child will get nil. Ruby also supports Kernel.fork, Kernel.exec and IO.pipe, but the book doesn’t go into it much, except that it’s platform dependent. Lastly, you can pass a block to it IO.popen. Works amazingly similar to File.open. Block runs, and when it’s done the popen is cleaned up. A naieve assumption again, however, because it’s difficult to do any error handling.
Well, that’s it for today. Next up is Unit testing. Blech. I may be almost ready to go on to ruby on rails. The second part of the book is “Ruby in its setting.” Talks about Command-Line arguments, namespaces, character encoding, documenting ruby, ruby and the web, and finally ruby and Microsloth Windows. May have to skim those chapters. It might be time to learn me some rails! And build something!