On Github trekdemo / ruby-threading
chief git blame analyst at DiNa Github/twitter @trekdemo
In computer science, a thread of execution is the smallest sequence of programmed instructions that can be managed independently by an operating system scheduler.
-- Wikipedia
Thread.main
Thread.current
Thread.new {}
By default, your code is always running a thread. Even if you don't create any
new threads, there's always at least one: the main thread.
Major difference between regular and main thread:
When the main thread exits, all other threads are immediately terminated and
the Ruby process exits.Concurrency and parallelism are two related but distinct concepts.
Concurrency : Task A and task B both need to happen independently of each other. A starts running, and then B starts before A is finished, but they not necessarily going to be executed simultaniusly.
Parallelism : Task A and task B both running in the same time, simultaniusly.
Concurrency: they don't have to run simultaniusly Concurrency: same things, but they run simultaniuslyConcurrent
>----> >---->> Task A
>-----> >--> >----->> Task B
Paralell
>-------->> Task A
>---------------------------->> Task B
...have real native OS threads and paralell execution.
require 'digest/md5'
3.times.map do
Thread.new do
Digest::MD5.hexdigest(rand)
end
end.each(&:value)
This computation will run simultaniusly in 3 threads with jruby, rubinius
and concurrently on mri.require 'open-uri'
3.times.map do
Thread.new do
open('http://digitalnatives.hu')
end
end.each(&:value)
Rubinius have fine-grained locks around the internal data structures, and helps gem (C extension) developers to avoid race conditions.
JRuby, does not support C extensions, you can use java based extension instead.
@results ||= "some value"
* Anything where there is only one shared instance is a globalif @result.nil? temp = "some value" @result = temp end
shared_mutex_accross_threads = Mutex.new
mutex.lock
mutex.unlock
mutex.synchronize {}
The name 'mutex' is shorthand for 'mutual exclusion.' If you wrap some section
of your code with a mutex, you guarantee that no two threads can enter that
section at the same time.These can be used to communicate between threads to synchronize resource access.
require 'thread'
array = []
mutex = Mutex.new
cond_var = ConditionVariable.new
Thread.new do
10.times do
mutex.synchronize do
sleep(rand)
array << rand
cond_var.signal
end
end
end
Thread.new do
10.times do
mutex.synchronize do
cond_var.wait(mutex) while array.empty?
puts "Processing #{array.shift}"
end
end
end
A ConditionVariable can be used to signal one (or many) threads when some
event happens, or some state changes, whereas mutexes are a means of
synchronizing access to resources.The only thread-safe data structure from standard lib. Can be implemented with an Array, a Mutex and a ConditionVariable.