|
Let's start with the general concepts of threads and multithreading.
I will briefly describe what each means, you can here more on this Wikipedia article if you want.
The results of a program that "splits" it's "job" into 2 or more "pieces" are threads of execution.This is a concept used for various reasons, one of which being improving overall speed of execution.The way threads are implemented depends on a variety of factors including operating system, processor type, number of processors or cores per processor.
Multithreading occurs when multiples thread are executed in parallel, not necessarily simultaneously.
Try to imagine the importance of threads by thinking how your world could be if you'd have to sit in front of your pc forced to use only one software at a time, reading email without listening to music at the same time, without reading the online edition of your favorite newspaper while waiting for the bulk to clear up the spam, or without chatting with a friend over IM while you skim through email subjects.
What if a server could only serve one request at a time? You'd be asking for a website's page and all the other hundreds browsing at the same time would have to wait till the server is done with you.
Nightmare, right? It would be, at least for me, an avid multitasker.So basically, multithreading can be seen a splitting a bigger processing job into smaller pieces that can be ran and solved more or less in parallel.
If you are familiar with fork processes and threads under Unix, it will be much easier for you to understand how Ruby threads these concepts, especially if you're particularly interested in multiprocessing.
To eliminate any confusion from the start, let's make a clear distinction between multithreading and multiprocessing.
You can split tasks of the same program, using multiple threads, or you can split tasks between different programs, using multiple processes.
For multiprocessing, you can use the same concepts as in Unix, pipe(for process intercommunication),fork(used for creating child processes), wait(used for temporarily holding execution of a process until another has finished) or exec(for "covering" processes).
A fork call will return the PID or process ID of the created child process to the father(parent) and nil into the child itself.
This might be useful to you also if you plan to gain extensive knowledge on multithreading and multiprocessing in Ruby, as I don't plan to get as technical as the tutorial I indicated does because my tutorial is written especially with beginners in mind and there are a lot of other things to worry first before getting to these 2 concepts.
This one might also be of some use to use, if again, you plan to dedicate more time to the subject
RubyGarden also provides an interesting mini advanced tutorial on multithreading.
Here's a pretty simple code sample trying to show you what you could do with threads.The program has 2 threads, one multiplying a number by 2, the other subtracting 2 from it.
x=2
Thread.new do
while x <= 32
x = x - 2
puts "Subtracted 2, the current number is #{x}\n"
end
puts "Stopping.Limit condition reached.\n"
end
while x <= 32
x = x * 2
puts "Multiplied by 2, the current number is #{x}\n"
end
Obviously, you start a new thread by using the new method on the class Thread.
When you use the new method, Ruby creates another thread that will run alongside the main thread, thus the result of the code above will not be the same as the one obtained after doing all the subtractions first and then doing the multiplications.
Another problem you will face if you decide to study the subject more is synchronizing access to data.Obviously, you'd want data access to be conducted in a civilized way, where processes don't read/write in chaotic manner.
You will need to learn about Mutex in order to do this and about how to avoid deadlocks.
|