Lyrical digression
For example, we are writing a server. The embodiment of the server is a looping, a constant survey of something. All small discrete is considered to be considered constant, and that is how a permanent connection is obtained.
Realities
Ruby has an infinite loop.
Copy Source | Copy HTML loop { puts " ." } # . puts " , ."
Copy Source | Copy HTML loop { puts " ." } # . puts " , ."
Copy Source | Copy HTML loop { puts " ." } # . puts " , ."
Copy Source | Copy HTML loop { puts " ." } # . puts " , ."
Copy Source | Copy HTML loop { puts " ." } # . puts " , ."
Copy Source | Copy HTML loop { puts " ." } # . puts " , ."
Those. you have to do everything before we started looping.
In addition, this operation is very sensitive for the processor. If we do not need a very frequent repetition, then the cycle can be put to sleep for a while.
Copy Source | Copy HTML
- loop {
- puts "Nothing will stop me."
- sleep ( 1 ) # one second sleep
- }
And if you need to perform operations with different frequencies, then within one cycle it is problematic.
Thread
To solve these problems, there are threads.
Typical flow
Copy Source | Copy HTML
- Thread .new {
- loop {
- puts "I thread"
- }
- }
First experience
Now I will show how I began to investigate Thread and what came as a surprise to me.
The first program with threads looked like I wrote above. When I launched it, nothing happened. The first thought that came to mind (and erroneous) was that the
stream needed to be launched , and I got into the dock in search of the “starting” method.
It turned out with the help of join
Without reading the description, I decided that
this is how the threads run . Further, for my own amusement, I made a watch:
Copy Source | Copy HTML
- thr_1 = Thread .new {
- loop {
- sleep ( 5 )
- puts "Five"
- }
- }
- thr_2 = Thread .new {
- loop {
- sleep ( 10 )
- puts "TEN"
- }
- }
- thr_3 = Thread .new {
- loop {
- sleep ( 1 )
- puts "tick"
- }
- }
Those. a program in which operations in cycles are performed with a different frequency (I wrote about it above), and literally accidentally discovered that thr_1.join (for example) “starts” all threads, and not just itself.
And then it was even stranger when I started trying to write in threads not eternal loops, but methods. They could be executed, partially executed, or not executed at all. The clouds were gathering, but through the pile of test programs I got to the truth, and here it is:
join is not a start!
As soon as we run our application, we get into Thread.main
If all operations in it end, the application closes. If there are other threads, the application closes, regardless of them.
For example, if, in addition to creating threads, there is nothing more to be done at all, then the program will terminate immediately, without executing, the code in the threads created - what happened to me at the beginning.
join makes a thread from which it is called asleep, until the end of the thread to which it is called.
Those. At the beginning, I made a sleeping Thread.main until the completion of thr_1. Thread.main became inactive, but did not end, waiting for the completion of the thr_1 thread, so the application did not end either, and the other threads happily continued to work.
Run threads with the sleep team!
The easiest way to extend Thread.main is to put it to sleep.
Copy Source | Copy HTML
- Thread .new {
- puts "Finally"
- }
- Thread .new {
- puts "we run!"
- }
- sleep 5 # put to sleep
- sleep # or forever
run
Sleeping streams, incl. Thread.main, you can run again with the run
And stop using sleep or Thread.stop methods.
Copy Source | Copy HTML
- thr = Thread .new {
- sleep #z z Z
- puts "..not sleep .."
- puts "and you don't sleep"
- Thread .main.run
- }
- Thread .new {
- sleep 1
- puts "Wake up!"
- thr.run
- }
- Thread .stop
All for today with threads. This is my first article (in general). I will listen to the reviews and, perhaps, continue the story :)