婷婷综合国产,91蜜桃婷婷狠狠久久综合9色 ,九九九九九精品,国产综合av

主頁 > 知識庫 > ruby中并發并行與全局鎖詳解

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

熱門標簽:電話機器人電話卡封號怎么辦 浦東上海400開頭的電話申請 邯鄲外呼調研線路 武漢呼叫中心外呼系統線路商 樂昌電話機器人 真人語音電銷機器人系統 北京語音電銷機器人價格 開封百應電銷機器人聯系方式 買了外呼系統不想用了怎么辦

前言

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

并發和并行

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

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

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

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

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

1、順序執行:

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

require 'benchmark'

def f1
 puts "sleep 3 seconds in f1\n"
 sleep 3
end

def f2
 puts "sleep 2 seconds in f2\n"
 sleep 2 
end

Benchmark.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)
end

def single_threads
 time = Time.now
 count = 0
 Thread.new do
 10000000.times { count += 1}
 end.join
end

Benchmark.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的時候, 明明實現了并行啊!

這個就是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)
end

def single_threads
 uri = URI("http://www.baidu.com")
 Thread.new do
 100.times { Net::HTTP.get(uri) }
 end.join
end

Benchmark.bm do |b|
 b.report { multiple_threads }
 b.report { single_threads }
end

 user  system  total  real
0.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 = 1
r = []
10.times do |e|

Thread.new {
 @c = 1
 @c += @a
 r  [e, @c]
}
end
r
## [[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 = 1
r = []
10.times do |e|

Thread.new {
 @c = 1
 puts @c
 @c += @a
 r  [e, @c]
}
end
r
## [[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 加快整體運算速度,有計劃了解一些.

總結

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

標簽:六安 松原 淄博 鄂州 石嘴山 宜春 河北 自貢

巨人網絡通訊聲明:本文標題《ruby中并發并行與全局鎖詳解》,本文關鍵詞  ruby,中,并發,并行,與,全局,;如發現本文內容存在版權問題,煩請提供相關信息告之我們,我們將及時溝通與處理。本站內容系統采集于網絡,涉及言論、版權與本站無關。
  • 相關文章
  • 下面列出與本文章《ruby中并發并行與全局鎖詳解》相關的同類信息!
  • 本頁收集關于ruby中并發并行與全局鎖詳解的相關信息資訊供網民參考!
  • 推薦文章
    婷婷综合国产,91蜜桃婷婷狠狠久久综合9色 ,九九九九九精品,国产综合av
    午夜电影网一区| 亚洲永久精品国产| 亚洲欧美一区二区三区极速播放 | 亚洲欧美成aⅴ人在线观看| 91在线观看一区二区| 精品一区二区三区在线播放| 国产精品福利一区二区| 日韩美女视频一区二区| 91小视频免费观看| 中文字幕在线观看一区二区| 日韩精品自拍偷拍| 26uuuu精品一区二区| 精品国产乱码久久| 日本韩国视频一区二区| 成人一区在线看| 国产精品一二三| 久草在线在线精品观看| 亚洲影视在线观看| 91福利视频在线| av不卡一区二区三区| 欧美日免费三级在线| 日本高清不卡aⅴ免费网站| 色综合久久中文综合久久97| 首页国产丝袜综合| 日韩欧美区一区二| 亚洲四区在线观看| 国产亚洲自拍一区| 日韩欧美另类在线| 亚洲免费av高清| 亚洲欧美激情插 | 成人黄色免费短视频| 久久久久9999亚洲精品| 亚洲欧洲日产国码二区| 国产精品久久久久国产精品日日| 日本一二三四高清不卡| 波多野结衣中文一区| 中文字幕一区二区三区在线播放| 日韩三级av在线播放| 99在线精品视频| 欧美另类videos死尸| 91福利国产精品| 欧美久久婷婷综合色| 91精品国产丝袜白色高跟鞋| 欧美三级日韩三级国产三级| 日本韩国一区二区| 久久看人人爽人人| 精品视频1区2区3区| 制服丝袜亚洲播放| 精品中文av资源站在线观看| 欧美系列亚洲系列| 欧美熟乱第一页| 欧美国产日韩在线观看| 成人免费视频国产在线观看| 亚洲精品水蜜桃| 国产成人一级电影| 一本色道久久综合亚洲aⅴ蜜桃 | 亚洲国产一区二区视频| 国产色爱av资源综合区| 欧美精品一区男女天堂| 欧美一级免费观看| 中文字幕一区二区三区在线观看| 亚洲国产综合色| 欧日韩精品视频| 在线欧美日韩国产| 亚洲第一av色| 成人黄色大片在线观看| 日韩精品中午字幕| 一区二区久久久| 亚洲综合色婷婷| 精品国内二区三区| 免费成人你懂的| 欧美日韩黄色一区二区| 欧美综合视频在线观看| 色综合久久精品| 亚洲成人一区在线| 国产91高潮流白浆在线麻豆 | 国产精品久久久久国产精品日日| 日韩一区二区三区视频在线 | 欧美韩国一区二区| 国产精品色噜噜| 国产精品一区二区三区网站| 在线免费亚洲电影| 亚洲大尺度视频在线观看| 国产成人免费av在线| 日韩一区二区免费电影| 欧美一级日韩免费不卡| 粉嫩av一区二区三区| 亚洲精品一区二区三区四区高清| 日韩国产在线观看一区| 高清成人在线观看| 日韩二区三区四区| 日本一区二区三级电影在线观看| 国产成人综合亚洲网站| 国产精品久久久久aaaa樱花| 天天亚洲美女在线视频| 青青草伊人久久| 久久精品亚洲乱码伦伦中文 | 色88888久久久久久影院野外| 色婷婷激情久久| 久久精品久久综合| 中文字幕一区在线| 一本大道久久a久久综合婷婷| 亚洲蜜桃精久久久久久久| 麻豆精品一二三| kk眼镜猥琐国模调教系列一区二区| 韩日欧美一区二区三区| 欧美mv日韩mv国产网站app| 午夜影院久久久| 韩国精品主播一区二区在线观看 | 精品处破学生在线二十三| 91精品国产91久久久久久最新毛片| 精品一区二区久久| 欧美一区中文字幕| 蜜桃免费网站一区二区三区| 色婷婷激情一区二区三区| 一道本成人在线| 午夜精品视频一区| 欧美性做爰猛烈叫床潮| 午夜精品123| 91视频在线看| 色婷婷亚洲综合| 亚洲天堂中文字幕| 国产精品1区2区3区在线观看| 91蜜桃视频在线| 99久久综合狠狠综合久久| 粉嫩av亚洲一区二区图片| 久久综合九色综合97_久久久| av一区二区三区在线| 日韩 欧美一区二区三区| 尤物av一区二区| 2022国产精品视频| 国产风韵犹存在线视精品| 国产精品区一区二区三| 7777精品伊人久久久大香线蕉| 欧美三级电影网| 岛国av在线一区| 亚洲电影第三页| 欧美日韩电影在线播放| 日韩视频一区二区| 91精品久久久久久久99蜜桃 | 免费欧美在线视频| 六月丁香婷婷久久| 有码一区二区三区| 中文字幕一区二区三区精华液| 欧美日韩成人综合天天影院| 亚洲靠逼com| 国产在线播放一区二区三区| 国产欧美1区2区3区| 图片区小说区区亚洲影院| 国产清纯在线一区二区www| 国产喷白浆一区二区三区| 日韩一区二区三区在线观看| 韩国v欧美v日本v亚洲v| 国产成人av影院| 久热成人在线视频| 欧美一区二区三区不卡| 国产人成亚洲第一网站在线播放 | 成人欧美一区二区三区白人| 在线精品视频一区二区| 欧美日韩免费高清一区色橹橹| a亚洲天堂av| 国内一区二区视频| 欧美精品久久久久久久久老牛影院| 久久99精品视频| 日韩国产欧美在线视频| www国产成人| 中文字幕在线不卡国产视频| 国产精品久久看| www国产亚洲精品久久麻豆| 热久久免费视频| 亚洲一区二区在线播放相泽| 美国十次了思思久久精品导航| 亚洲欧洲国产日韩| 日韩欧美国产麻豆| 美女免费视频一区| 日韩在线一区二区| 亚洲视频一区在线观看| 国产成人综合视频| 国产一区二区三区免费在线观看| 国产自产视频一区二区三区| 欧美高清视频在线高清观看mv色露露十八 | 国产精品小仙女| 91免费在线看| 欧美疯狂做受xxxx富婆| 风间由美一区二区三区在线观看 | 免费在线观看视频一区| 国产午夜一区二区三区| 亚洲福利视频导航| 成人av电影在线观看| 亚洲欧美区自拍先锋| 国产在线精品一区二区不卡了| 国产亚洲精品久| 日本成人在线看| 最新中文字幕一区二区三区 | 99精品视频在线播放观看| 成人不卡免费av| 91免费国产在线观看| 亚洲欧美激情在线| 日韩电影在线免费| 国产精品卡一卡二|