亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > Ruby > 正文

ruby中并發并行與全局鎖詳解

2020-03-29 11:46:28
字體:
來源:轉載
供稿:網友

前言

本文主要給大家介紹了關于ruby/244826.html">ruby并發并行和全局鎖的相關內容,分享出來供大家參考學習,下面話不多說了,來一起看看詳細的介紹吧。

并發和并行

在開發時,我們經常會接觸到兩個概念: 并發和并行,幾乎所有談到并發和并行的文章都會提到一點: 并發并不等于并行.那么如何理解這句話呢?

  • 并發: 廚師同時接收到了2個客人點了的菜單需要處理.
  • 順序執行: 如果只有一個廚師,那么他只能一個菜單接著一個菜單的去完成.
  • 并行執行: 如果有兩個廚師,那么就可以并行,兩個人一起做菜.

將這個例子擴展到我們的web開發中, 就可以這樣理解:

  • 并發:服務器同時收到了兩個客戶端發起的請求.
  • 順序執行:服務器只有一個進程(線程)處理請求,完成了第一個請求才能完成第二個請求,所以第二個請求就需要等待.
  • 并行執行:服務器有兩個進程(線程)處理請求,兩個請求都能得到響應,而不存在先后的問題.

根據上述所描述的例子,我們在 ruby 中怎么去模擬出這樣的一個并發行為呢? 看下面這一段代碼:

1、順序執行:

模擬只有一個線程時的操作.

require 'benchmark'def f1 puts "sleep 3 seconds in f1/n" sleep 3enddef f2 puts "sleep 2 seconds in f2/n" sleep 2 endBenchmark.bm do |b| b.report do f1 f2 end end## ## user  system  total  real## sleep 3 seconds in f1## sleep 2 seconds in f2## 0.000000 0.000000 0.000000 ( 5.009620)

上述代碼很簡單,用 sleep 模擬耗時的操作.順序執行時候的消耗時間.

2、并行執行

模擬多線程時的操作

# 接上述代碼Benchmark.bm do |b| b.report do threads = [] threads << Thread.new { f1 } threads << Thread.new { f2 } threads.each(&:join) end end#### user  system  total  real## sleep 3 seconds in f1## sleep 2 seconds in f2## 0.000000 0.000000 0.000000 ( 3.005115)

我們發現多線程下耗時和f1的耗時相近,這與我們預期的一樣,采用多線程可以實現并行.

Ruby 的多線程能夠應付 IO Block,當某個線程處于 IO Block 狀態時,其它的線程還可以繼續執行,從而使整體處理時間大幅縮短.

Ruby 中的線程

上述的代碼示例中使用了 ruby 中 Thread 的線程類, Ruby可以很容易地寫Thread類的多線程程序.Ruby線程是一個輕量級的和有效的方式,以實現在你的代碼的并行.

接下來來描述一段并發時的情景

 def thread_test time = Time.now threads = 3.times.map do   Thread.new do  sleep 3   end end puts "不用等3秒就可以看到我:#{Time.now - time}" threads.map(&:join) puts "現在需要等3秒才可以看到我:#{Time.now - time}" end test ## 不用等3秒就可以看到我:8.6e-05 ## 現在需要等3秒才可以看到我:3.003699

Thread的創建是非阻塞的,所以文字立即就可以輸出.這樣就模擬了一個并發的行為.每個線程sleep 3 秒,在阻塞的情況下,多線程可以實現并行.

那么這個時候我們是不是就完成了并行的能力呢?

很遺憾,我上述的描述中只是提到了我們在非阻塞的情況下可以模擬了并行.讓我們再看一下別的例子:

require 'benchmark'def multiple_threads count = 0 threads = 4.times.map do  Thread.new do  2500000.times { count += 1} end end threads.map(&:join)enddef single_threads time = Time.now count = 0 Thread.new do 10000000.times { count += 1} end.joinendBenchmark.bm do |b| b.report { multiple_threads } b.report { single_threads }end##  user  system  total  real## 0.600000 0.010000 0.610000 ( 0.607230)## 0.610000 0.000000 0.610000 ( 0.623237)

從這里可以看出,即便我們將同一個任務分成了4個線程并行,但是時間并沒有減少,這是為什么呢?

因為有全局鎖(GIL)的存在?。?!

全局鎖

我們通常使用的ruby采用了一種稱之為GIL的機制.

即便我們希望使用多線程來實現代碼的并行, 由于這個全局鎖的存在, 每次只有一個線程能夠執行代碼,至于哪個線程能夠執行, 這個取決于底層操作系統的實現。

即便我們擁有多個CPU, 也只是為每個線程的執行多提供了幾個選擇而已。

我們上面代碼中每次只有一個線程可以執行 count += 1 .

Ruby 多線程并不能重復利用多核 CPU,使用多線程后整體所花時間并不縮短,反而由于線程切換的影響,所花時間可能還略有增加。

但是我們之前sleep的時候, 明明實現了并行?。?/p>

這個就是Ruby設計高級的地方——所有的阻塞操作是可以并行的,包括讀寫文件,網絡請求在內的操作都是可以并行的.

require 'benchmark'require 'net/http'# 模擬網絡請求def multiple_threads uri = URI("http://www.baidu.com") threads = 4.times.map do  Thread.new do  25.times { Net::HTTP.get(uri) } end end threads.map(&:join)enddef single_threads uri = URI("http://www.baidu.com") Thread.new do 100.times { Net::HTTP.get(uri) } end.joinendBenchmark.bm do |b| b.report { multiple_threads } b.report { single_threads }end user  system  total  real0.240000 0.110000 0.350000 ( 3.659640)0.270000 0.120000 0.390000 ( 14.167703)

在網絡請求時程序發生了阻塞,而這些阻塞在Ruby的運行下是可以并行的,所以在耗時上大大縮短了.

GIL 的思考

那么,既然有了這個GIL鎖的存在,是否意味著我們的代碼就是線程安全了呢?

很遺憾不是的,GIL 在ruby 執行中會某一些工作點時切換到另一個工作線程去,如果共享了一些類變量時就有可能踩坑.

那么, GIL 在 ruby代碼的執行中什么時候會切換到另外一個線程去工作呢?

有幾個明確的工作點:

  • 方法的調用和方法的返回, 在這兩個地方都會檢查一下當前線程的gil的鎖是否超時,是否要調度到另外線程去工作
  • 所有io相關的操作, 也會釋放gil的鎖讓其它線程來工作
  • 在c擴展的代碼中手動釋放gil的鎖
  • 還有一個比較難理解, 就是ruby stack 進入 c stack的時候也會觸發gil的檢測

一個例子

@a = 1r = []10.times do |e|Thread.new { @c = 1 @c += @a r << [e, @c]}endr## [[3, 2], [1, 2], [2, 2], [0, 2], [5, 2], [6, 2], [7, 2], [8, 2], [9, 2], [4, 2]]

上述中r 里 雖然e的前后順序不一樣, 但是@c的值始終保持為 2 ,即每個線程時都能保留好當前的 @c 的值.沒有線程簡的調度.

如果在上述代碼線程中加入 可能會觸發GIL的操作 例如 puts 打印到屏幕:

@a = 1r = []10.times do |e|Thread.new { @c = 1 puts @c @c += @a r << [e, @c]}endr## [[2, 2], [0, 2], [4, 3], [5, 4], [7, 5], [9, 6], [1, 7], [3, 8], [6, 9], [8, 10]]

這個就會觸發GIL的lock, 數據異常了.

小結

Web 應用大多是 IO 密集型的,利用 Ruby 多進程+多線程模型將能大幅提升系統吞吐量.其原因在于:當Ruby 某個線程處于 IO Block 狀態時,其它的線程還可以繼續執行,從而降低 IO Block 對整體的影響.但由于存在 Ruby GIL (Global Interpreter Lock),MRI Ruby 并不能真正利用多線程進行并行計算.

PS. 據說 JRuby 去除了GIL,是真正意義的多線程,既能應付 IO Block,也能充分利用多核 CPU 加快整體運算速度,有計劃了解一些.

總結

以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,如果有疑問大家可以留言交流,謝謝大家對VEVB武林網的支持。

 

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
国产成人在线一区| 在线观看精品自拍私拍| 美日韩精品免费观看视频| 在线视频日韩精品| 国产精品video| 日韩av在线导航| 亚洲jizzjizz日本少妇| 久久精品中文字幕一区| 亚洲免费精彩视频| 久久影视电视剧免费网站清宫辞电视| 波霸ol色综合久久| 国产精品极品在线| 日韩美女视频免费在线观看| 亚洲最大福利网站| 大桥未久av一区二区三区| 91久久国产婷婷一区二区| 国产第一区电影| 日韩激情av在线播放| 国产欧美精品在线播放| 日韩av综合网| 国产精品久久久久久久久久| 国产精彩精品视频| 国内精品久久久久| 欧美精品18videos性欧| 亚洲欧美一区二区三区四区| 在线精品视频视频中文字幕| 综合欧美国产视频二区| 午夜精品美女自拍福到在线| 欧美又大粗又爽又黄大片视频| 国产精品一区二区av影院萌芽| 久久九九精品99国产精品| 91久久精品在线| 日韩av在线网址| 夜夜嗨av色综合久久久综合网| 国内精品一区二区三区| 91av在线播放视频| 欧美中文在线观看| 亚洲影视九九影院在线观看| 日韩激情视频在线| 午夜精品久久久久久久男人的天堂| 日韩中文字幕视频在线| 国产精品影片在线观看| 国产精品自拍偷拍视频| 欧美日韩国产成人高清视频| 国产精品久久久久久久久久尿| 色www亚洲国产张柏芝| 91亚洲国产成人精品性色| 国产亚洲综合久久| 亚洲japanese制服美女| 欧美黄色www| 日韩国产高清视频在线| 欧美另类极品videosbest最新版本| 亚洲三级免费看| 91日韩在线播放| 成人性生交xxxxx网站| 亚洲国产小视频| 国内精品久久久久伊人av| 精品国内亚洲在观看18黄| 国产成人综合一区二区三区| 亚洲欧美精品一区二区| www.欧美精品一二三区| 欧美一级大片在线免费观看| 亚洲免费电影一区| 国产日韩在线一区| 国产精品久久久久免费a∨| 国产69精品久久久久久| 51视频国产精品一区二区| 欧美午夜性色大片在线观看| 欧美一性一乱一交一视频| 日韩欧美高清视频| 欧美成人中文字幕| 亚洲一二在线观看| 日韩天堂在线视频| 91豆花精品一区| 亚洲a∨日韩av高清在线观看| 91免费观看网站| 亚洲精品国产精品久久清纯直播| 国产精品久久久av| 9.1国产丝袜在线观看| xxxxx91麻豆| 国产成人小视频在线观看| 97视频在线观看网址| 69**夜色精品国产69乱| 亚洲国产欧美一区二区丝袜黑人| 成人xxxx视频| 亚洲福利在线观看| 成人黄色免费看| 亚洲人线精品午夜| 欧美精品做受xxx性少妇| 日韩视频免费大全中文字幕| 九九九热精品免费视频观看网站| 日韩大片免费观看视频播放| 欧美精品videos另类日本| 亚洲欧美一区二区激情| 97视频免费观看| 91精品国产91久久久久久不卡| 亚洲男人的天堂在线| 久久久精品欧美| 久久影院在线观看| 久久亚洲精品一区二区| 色婷婷成人综合| 2020国产精品视频| 国产福利视频一区二区| 成人免费网站在线看| 日韩精品久久久久久久玫瑰园| 91在线视频成人| 欧美激情一级欧美精品| 中文字幕日韩专区| 日韩免费精品视频| 亚洲成人精品av| 在线观看欧美日韩国产| 萌白酱国产一区二区| 96精品视频在线| 日本亚洲精品在线观看| 久久久久久97| 成人免费直播live| 亚洲精品久久久久中文字幕欢迎你| 欧洲精品久久久| 亚洲free嫩bbb| 91久久国产精品| 亚洲成人性视频| 欧美激情国产日韩精品一区18| 91日韩在线播放| 91精品国产色综合久久不卡98口| 色久欧美在线视频观看| 日本一区二区三区在线播放| 亚洲在线免费观看| 国产精品丝袜久久久久久高清| 精品国产鲁一鲁一区二区张丽| 欧美另类在线播放| 欧美在线观看网站| 国产91成人video| 亚洲精品国精品久久99热| 国产噜噜噜噜久久久久久久久| 国产精品成人av在线| 麻豆国产精品va在线观看不卡| 中文字幕日韩欧美在线| 亚洲免费一级电影| 精品成人av一区| 亚洲一区二区自拍| www.日韩免费| xxx成人少妇69| 欧美日韩久久久久| 亚洲第一区中文99精品| 日韩有码在线视频| 国产亚洲xxx| 77777亚洲午夜久久多人| 26uuu日韩精品一区二区| 在线看欧美日韩| 538国产精品一区二区在线| 美女久久久久久久久久久| 97在线精品国自产拍中文| 国模私拍一区二区三区| 深夜福利国产精品| 国产精品久久久久久久久久尿| 久色乳综合思思在线视频| 国产欧美va欧美va香蕉在线| 中文字幕亚洲第一| 国产一区二区三区免费视频| 日韩高清免费在线| 一个色综合导航| 456国产精品| 国产精品视频在线观看| 亚洲综合社区网|