views:

124

answers:

4

Is there some way to run 2 threads at the same time?

I want to have my app run its current function and then bring up another thread running another function, that can change variables in the first thread.

A: 

http://ruby-doc.org/core/classes/Thread.html
Remember that only in JRuby threads are truly parallel (other interpreters implement GIL). From here:

# mutexsyncex.rb  
require 'thread'  # For Mutex class in Ruby 1.8  

# A BankAccount has a name, a checking amount, and a savings amount  
class BankAccount  
  def initialize(name, checking, savings)  
    @name,@checking,@savings = name,checking,savings  
    @lock = Mutex.new  # For thread safety  
  end  

  # Lock account and transfer money from savings to checking  
  def transfer_from_savings(x)  
    @lock.synchronize {  
      @savings -= x  
      @checking += x  
    }  
  end  

  # Lock account and report current balances  
  def report  
    @lock.synchronize {  
      "#@name\nChecking: #@checking\nSavings: #@savings"  
    }  
  end  
end 

ba = BankAccount.new('me', 1, 400)

ba.transfer_from_savings(10);
puts ba.report
clyfe
+1  A: 

http://ruby-doc.org/core/classes/Thread.html

x = 2
Thread.new do
    x = 3
end
x = 4

For tru concurency - >=2 cores or >= processors - but it may not work if implementation is single-threaded.

Maciej Piechotka
+3  A: 

If you want to run two threads at the same time, the entire execution stack has to be capable of doing that. Let's start at the top:

  1. Ruby itself is capable of running two threads at the same time, no problem there. However, Ruby is just a programming language, i.e. just a bunch of rules. In order to run your program, you need a Ruby implementation. Unfortunately, many popular Ruby implementations are not capable of running multiple threads at the same time, including MRI, YARV and Rubinius. In fact, the only production-ready Ruby implementation which can run threads simultaneously is JRuby. (IronRuby too, but that is technically not yet production-ready although the final 1.0 release is probably only days away.)
  2. But JRuby (and IronRuby) don't actually implement threads themselves, they just use the underlying platform's threads. I.e. JRuby maps Ruby threads to JVM threads and IronRuby maps them to CLI threads. So, the underlying platform has to be able to run threads in parallel, too.
  3. Again: both the JVM and the CLI are in principle capable of running threads in parallel, but the JVM and the CLI are just specifications, they are just pieces of paper. In order to run your code, you need an implementation of those specifications, and not all of them do support truly concurrent threads.
  4. Even if your platform implementation supports truly concurrent threads, they might themselves delegate their threading implementation to the underlying OS, just like JRuby delegates to the JVM. .NET, Mono, HotSpot and JRockit for example (which are the most popular implementations of the CLI and the JVM respectively) use native OS threads for their platform threads. So, obviously, the OS has to be able to run threads in parallel. And again: not all of them are.
  5. And, of course, all the parallelism in the OS doesn't help if you only have one CPU. If you want two threads to run at the same time, you need either two CPUs, two cores or two simultaneous hardware threads.
Jörg W Mittag
"all the parallelism in the OS doesn't help if you only have one CPU" - Its worth noting that threads can (and I shudder to say this) make the programming of the tasks involved simpler, providing benefit even if they're not truly run in parallel. There are a number of cases where "what's being done" can be expressed more clearly if the code itself doesn't need to handle task switching. An example is a UI thread and a worker thread, switching between them handled by the OS, even if it doesn't run both at the same time.
RHSeeger
@RHSeeger: Yep, using threads for asynchronous programming certainly works. However, the question doesn't mention asynchronous programming, it specifically says "at the same time" which pretty much requires more than one CPU. (Although I believe that for pretty much every problem you can use threads for, there is a much better solution using something else. For asynchronous programming for example, I would prefer something like Functional Reactive Programming. For concurrency Agents, Actors, Join Patterns, Futures or Software Transactional Memory.)
Jörg W Mittag
@Jörg: Fair enough. In general, I agree that threads are most often not the first choice on my list either. Depending on the language and libraries available, though, they are a reasonable choice for generating the most "expressive" code sometimes.
RHSeeger
A: 

first, I'm gonna answer your question:

thread_1 = Thread.new do #do something here end

thread_2 = Thread.new do #do something here end

thread_1.join thread_2.join(timeout_in_seconds)

the Thread#join method makes the main thread to wait until the joined threads finishes, if you specify a timeout in seconds ruby will close the thread once those seconds reached.

Now, the truth, there's no real concurrency in ruby 1.8 with the Matz Ruby Interpreter (MRI) and there's no real concurrency with only one processor though. please read this page => http://www.igvita.com/2008/11/13/concurrency-is-a-myth-in-ruby/

The MRI tries to cheat you using what's called Green Threads (http://en.wikipedia.org/wiki/Green_threads) which means that the Ruby interpreter takes care of everything to do with threads, not the OS, the other kind of threads, the ones really concurrent are called native threads and Ruby 1.9 support them through YARV but it doesn't mean that every Ruby thread runs in parallel because YARV has global VM lock (global interpreter lock or GIL) so concurrency is a myth in ruby and it'll be for a long time.

raf