Ruby Multi-Threading potential and vulnerability analysis _ruby topics

Source: Internet
Author: User


Web applications are mostly IO-intensive, and using Ruby's multi-process + multithreaded model will greatly increase system throughput. The reason for this is that when a ruby thread is in the IO block state, other threads can continue to execute. But because of Ruby GIL (Global interpreter Lock), MRI Ruby does not really use multithreading for parallel computing. JRuby removed the GIL, which is a true multi-threaded, capable of both dealing with IO blocks and making full use of multi-core CPUs to speed up the overall operation.



The above is more abstract, the following is illustrated with examples.



Ruby Multithreading and IO block



Look at the following code (for demonstration purposes, no actual use):


 code as follows:

# FILE:BLOCK_IO1.RB


def func1
Puts "sleep 3 seconds in func1\n"
Sleep (3)
End

def FUNC2
Puts "Sleep 2 seconds in func2\n"
Sleep (2)
End

def func3
Puts "sleep 5 seconds in func3\n"
Sleep (5)
End

Func1
Func2
Func3





The code is simple, 3 ways to simulate a time-consuming IO operation with sleep. The results of the Run code (Environment MRI Ruby 1.9.3) are:


 code as follows:

$ Time Ruby Block_io1.rb
Sleep 3 seconds in func1
Sleep 2 seconds in Func2
Sleep 5 seconds in func3


Real 0m11.681s
User 0m3.086s
SYS 0m0.152s





Slow, time spent on sleep, a total of more than 10 seconds.



In a multi-threaded manner, rewrite as follows:


code as follows:

# FILE:BLOCK_IO2.RB


def func1
Puts "sleep 3 seconds in func1\n"
Sleep (3)
End

def FUNC2
Puts "Sleep 2 seconds in func2\n"
Sleep (2)
End

def func3
Puts "sleep 5 seconds in func3\n"
Sleep (5)
End

Threads = []
Threads << thread.new {func1}
Threads << thread.new {FUNC2}
Threads << thread.new {func3}

Threads.each {|t| T.join}





The results of the operation are:


code as follows:

$ Time Ruby Block_io2.rb
Sleep 3 seconds in func1
Sleep 2 seconds in Func2
Sleep 5 seconds in func3


Real 0m6.543s
User 0m3.169s
SYS 0m0.147s





It took a total of 6 seconds, significantly faster, and only a little more than the longest sleep 5 seconds.



The above example shows that Ruby's multithreading is capable of dealing with IO block, and that when a thread is in IO block state, other threads can continue to perform, which shortens the overall processing time.




the impact of Ruby GIL



Or look at a piece of code first (demo purpose):





 code as follows:

# FILE:GIL1.RB


Require ' securerandom '
Require ' zlib '

data = Securerandom.hex (4096000)

16.times {Zlib::D eflate.deflate (data)}





The code first randomly generates some data, then compresses it, the compression is very CPU-intensive, and the results of my machine (dual-core CPU, MRI Ruby 1.9.3) run as follows:


 code as follows:

$ Time Ruby Gil1.rb


Real 0m8.572s
User 0m8.359s
SYS 0m0.102s





To a multithreaded version, the code is as follows:


 code as follows:

# FILE:GIL2.RB


Require ' securerandom '
Require ' zlib '

data = Securerandom.hex (4096000)

Threads = []
16.times do
Threads << thread.new {Zlib::D eflate.deflate (data)}
End

Threads.each {|t| T.join}





The results of a multithreaded version run are as follows:


 code as follows:

$ Time Ruby Gil2.rb


Real 0m8.616s
User 0m8.377s
SYS 0m0.211s





As can be seen from the results, because of the presence of the MRI Ruby GIL, Ruby multithreading does not re-use multi-core CPUs, the overall time spent using multiple threads is not shortened, but due to the impact of thread switching, the time spent slightly increased.



JRuby removed GIL.



Using JRuby (my machine is JRuby 1.7.0) runs gil1.rb and gil2.rb and gets very different results.





 code as follows:

$ Time JRuby gil1.rb


Real 0m12.225s
User 0m14.060s
SYS 0m0.615s


 code as follows:

$ Time JRuby gil2.rb


Real 0m7.584s
User 0m22.822s
SYS 0m0.819s


As you can see, when JRuby uses multiple threads, the overall uptime is significantly shortened (7.58:12.22), because JRuby removes the GIL and can actually execute multiple threads in parallel, leveraging multi-core CPUs.





Summary: Ruby multithreading can still execute other threads while at one thread IO block, thus reducing the overall impact of Io block, but because of the presence of the MRI Ruby GIL, MRI Ruby is not really parallel execution, JRuby removed the GIL and can do real A positive multithreaded parallel execution.


Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.