|
Daniel Azuma
|
||
|
Ruby threads and Kernel#require
Posted on Wed, Dec 12, 2007, at 03:08 PM
For people like me with a Java background, one of the first things we bemoan and disparage when learning Ruby is its thread support. Simply put, Ruby threads are green threads, meaning they are implemented in user space. Among other things, this means they cannot be scheduled onto multiple processors or cores because the operating system does not know about them. There are other issues, such as the fact that often-used libraries such as ActiveRecord are not thread-safe. This article gives a brief but fairly good overview of the issues, relevant to the current MRI 1.8 implementation. InfoQ also published a very interesting article last spring on the pros and cons of different threading strategies related to Ruby. I recently had to design a multithreaded library for Zoodango’s deployment system, and I ran into another gotcha that I’m sure is known by someone, but I haven’t seen documented yet. Basically, the Let’s consider an example. Suppose, we have a ruby file ”
The As far as I can (experimentally) determine, the check-and-set that controls the “already loaded” flag occurs right at the beginning of the require method. So the following is a potential run of the above code:
You could argue that the above example is contrived. But this takes place in real code too. I ran into it when using Jamis Buck’s excellent library Net::SSH. Net::SSH lazily loads parts of its implementation as they are needed, executing a bunch of I’m still searching for a good general solution for this. (And I haven’t mucked with the ruby trunk so I don’t know if it’s still an issue in 1.9.) For now, what I’ve done is attempt to wrap code that I know could contain dynamic Update (27 June 2008) Net::SSH 2.0 and related libraries do in fact ditch the Needle dependency, so this issue no longer tends to show up when multiple threads access Net::SSH. However, the underlying issue with Kernel#require is still there.
5 Comments
Hi. I’ve encountered the same problems. I checked it and ruby from trunk has the same behaviour. I think that best solution will be writing thread safe “require” method. My proposal:
Your example with my solution: http://pastie.caboo.se/128951 # foo.rb http://pastie.caboo.se/128952 # main.rb run: ruby main.rb I think that it could be not 100% safe. I didn't check how it will run if there is nested require (file1 require file2, which require file3 etc.). @Radarek, as I see it, there are two problems. A The other problem is one of lock ordering. The following code, for example, could deadlock: main.rb:
foo.rb:
If thread There probably exists some different mutual exclusion primitive that will solve it, but I haven’t had the chance to sit down and work it out yet. I recently had similar problems running net-sftp with multiple threads and found a workaround that appears to work (http://discuss.joyent.com/viewtopic.php?id=18275). However, you may also want to check out the new net-ssh and net-sftp version 2 that Jamis posted links to awhile back (http://weblog.jamisbuck.org/2007/7/29/net-ssh-revisited). He rewrote the ssh and sftp gems, taking needle out. @Ajay: Thanks. I took a look at your discussion on Joyent. It looks like you’re trying to use threads to parallelize operations on the same SSH session. I’m taking a generally different approach. Net::SSH and Net::SFTP actually have parallelism built in. A single connection can run multiple operations (i.e. channels) in parallel, and you generally don’t create threads outside the library to do it. Instead, there are asynchronous versions of (nearly) all the operations. You just start them all up, register some callbacks, and then call What I’m trying to do is use threads to parallelize operations across multiple servers. Each such connection has its own Net::SSH session, and thus its own session loop. Calling Thanks for pointing me at the upcoming net-ssh and net-sftp version 2. I hadn’t noticed those before. Guess I need to pay more attention to Jamis’s blog… :-) I’ll take a look at the previews. Comments are disabled for this article.
|
Recent
Tags
Random blogs
|
|