Ensuring That a Thread Executes

Let’s return to the problem I had in the previous programs. Recall that I created two threads, but the program finished before either of them had a chance to run fully. I fixed this by inserting a fixed-length delay using the sleep method. Deliberately introducing gratuitous delays into your programs is not something you would want to do as a general rule. Fortunately, Ruby has a more civilized way of ensuring that a thread has time to execute. The join method forces the calling thread (for example, the main thread) to suspend its own execution (so it doesn’t just terminate the program) until the thread that calls join has completed:

join.rb

words = ["hello", "world", "goodbye", "mars" ]
numbers = [1,2,3,4,5,6,7,8,9,10]

Thread.new{
    words.each{ |word| puts( word ) }
}.join

Thread.new{
    numbers.each{ |number| puts( number ) }
}.join

At first sight, this looks like progress since both threads get the time they need to execute and you haven’t had to introduce any unnecessary delays. However, when you take a look at the output, you will see that the threads run in sequence—the second thread starts to run after the first thread has finished. This is why the output shows first all the words, displayed in the first Thread, and then all the numbers, displayed in the second Thread. But what you really want to do is get the two threads to run simultaneously, with Ruby switching from one to the next to give each thread a slice of the available processing time.

The next program, threads3.rb, shows one way of achieving this. It creates two threads, as before; however, this time it assigns each thread to a variable, namely, wordsThread and numbersThread:

threads3.rb

wordsThread = Thread.new{
    words.each{ |word| puts( word ) }
}
numbersThread = Thread.new{
    numbers.each{ |number| puts( number ) }
}

Now it puts these threads into an array and calls the each method to pass them into a block where they are received by the block variable, t, which simply calls the join method on each thread:

[wordsThread, numbersThread].each{ |t| t.join }

As you will see from the output, the two threads now run “in parallel,” so their output is jumbled up, but there is no artificial delay, and the total execution time is negligible.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.189.178.237