一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

腳本之家,腳本語言編程技術(shù)及教程分享平臺!
分類導(dǎo)航

Python|VBS|Ruby|Lua|perl|VBA|Golang|PowerShell|Erlang|autoit|Dos|bat|

服務(wù)器之家 - 腳本之家 - Ruby - 初步講解Ruby編程中的多線程

初步講解Ruby編程中的多線程

2020-04-24 11:00goldensun Ruby

這篇文章主要介紹了初步講解Ruby編程中的多線程,線程是各種編程語言學(xué)習(xí)當(dāng)中的重點和難點,需要的朋友可以參考下

每個正在系統(tǒng)上運行的程序都是一個進(jìn)程。每個進(jìn)程包含一到多個線程。

線程是程序中一個單一的順序控制流程,在單個程序中同時運行多個線程完成不同的工作,稱為多線程。

Ruby 中我們可以通過 Thread 類來創(chuàng)建多線程,Ruby的線程是一個輕量級的,可以以高效的方式來實現(xiàn)并行的代碼。
創(chuàng)建 Ruby 線程

要啟動一個新的線程,只需要調(diào)用 Thread.new 即可:

?
1
2
3
4
5
# 線程 #1 代碼部分
Thread.new {
 # 線程 #2 執(zhí)行代碼
}
# 線程 #1 執(zhí)行代碼

實例

以下實例展示了如何在Ruby程序中使用多線程:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#!/usr/bin/ruby
 
def func1
  i=0
  while i<=2
   puts "func1 at: #{Time.now}"
   sleep(2)
   i=i+1
  end
end
 
def func2
  j=0
  while j<=2
   puts "func2 at: #{Time.now}"
   sleep(1)
   j=j+1
  end
end
 
puts "Started At #{Time.now}"
t1=Thread.new{func1()}
t2=Thread.new{func2()}
t1.join
t2.join
puts "End at #{Time.now}"

以上代碼執(zhí)行結(jié)果為:

?
1
2
3
4
5
6
7
8
Started At Wed May 14 08:21:54 -0700 2014
func1 at: Wed May 14 08:21:54 -0700 2014
func2 at: Wed May 14 08:21:54 -0700 2014
func2 at: Wed May 14 08:21:55 -0700 2014
func1 at: Wed May 14 08:21:56 -0700 2014
func2 at: Wed May 14 08:21:56 -0700 2014
func1 at: Wed May 14 08:21:58 -0700 2014
End at Wed May 14 08:22:00 -0700 2014

線程生命周期

1、線程的創(chuàng)建可以使用Thread.new,同樣可以以同樣的語法使用Thread.start 或者Thread.fork這三個方法來創(chuàng)建線程。

2、創(chuàng)建線程后無需啟動,線程會自動執(zhí)行。

3、Thread 類定義了一些方法來操控線程。線程執(zhí)行Thread.new中的代碼塊。

4、線程代碼塊中最后一個語句是線程的值,可以通過線程的方法來調(diào)用,如果線程執(zhí)行完畢,則返回線程值,否則不返回值直到線程執(zhí)行完畢。

5、Thread.current 方法返回表示當(dāng)前線程的對象。 Thread.main 方法返回主線程。

6、通過 Thread.Join 方法來執(zhí)行線程,這個方法會掛起主線程,直到當(dāng)前線程執(zhí)行完畢。
線程狀態(tài)

線程有5種狀態(tài):

初步講解Ruby編程中的多線程

線程和異常

當(dāng)某線程發(fā)生異常,且沒有被rescue捕捉到時,該線程通常會被無警告地終止。但是,若有其它線程因為Thread#join的關(guān)系一直等待該線程的話,則等待的線程同樣會被引發(fā)相同的異常。

?
1
2
3
4
5
6
7
8
9
begin
 t = Thread.new do
  Thread.pass  # 主線程確實在等join
  raise "unhandled exception"
 end
 t.join
rescue
 p $! # => "unhandled exception"
end

使用下列3個方法,就可以讓解釋器在某個線程因異常而終止時中斷運行。

  •     啟動腳本時指定-d選項,并以調(diào)試模時運行。
  •     用Thread.abort_on_exception設(shè)置標(biāo)志。
  •     使用Thread#abort_on_exception對指定的線程設(shè)定標(biāo)志。

當(dāng)使用上述3種方法之一后,整個解釋器就會被中斷。

?
1
2
t = Thread.new { ... }
t.abort_on_exception = true

線程同步控制

在Ruby中,提供三種實現(xiàn)同步的方式,分別是:

1. 通過Mutex類實現(xiàn)線程同步

2. 監(jiān)管數(shù)據(jù)交接的Queue類實現(xiàn)線程同步

3. 使用ConditionVariable實現(xiàn)同步控制
通過Mutex類實現(xiàn)線程同步

通過Mutex類實現(xiàn)線程同步控制,如果在多個線程鐘同時需要一個程序變量,可以將這個變量部分使用lock鎖定。 代碼如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#encoding:gbk
require "thread"
puts "Synchronize Thread"
 
@num=200
@mutex=Mutex.new
 
def buyTicket(num)
  @mutex.lock
    if @num>=num
      @num=@num-num
      puts "you have successfully bought #{num} tickets"
    else
      puts "sorry,no enough tickets"
    end
  @mutex.unlock
end
 
ticket1=Thread.new 10 do
  10.times do |value|
  ticketNum=15
  buyTicket(ticketNum)
  sleep 0.01
  end
end
 
ticket2=Thread.new 10 do
  10.times do |value|
  ticketNum=20
  buyTicket(ticketNum)
  sleep 0.01
  end
end
 
sleep 1
ticket1.join
ticket2.join

輸出結(jié)果如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
Synchronize Thread
you have successfully bought 15 tickets
you have successfully bought 20 tickets
you have successfully bought 15 tickets
you have successfully bought 20 tickets
you have successfully bought 15 tickets
you have successfully bought 20 tickets
you have successfully bought 15 tickets
you have successfully bought 20 tickets
you have successfully bought 15 tickets
you have successfully bought 20 tickets
you have successfully bought 15 tickets
sorry,no enough tickets
sorry,no enough tickets
sorry,no enough tickets
sorry,no enough tickets
sorry,no enough tickets
sorry,no enough tickets
sorry,no enough tickets
sorry,no enough tickets
sorry,no enough tickets

除了使用lock鎖定變量,還可以使用try_lock鎖定變量,還可以使用Mutex.synchronize同步對某一個變量的訪問。
監(jiān)管數(shù)據(jù)交接的Queue類實現(xiàn)線程同步

Queue類就是表示一個支持線程的隊列,能夠同步對隊列末尾進(jìn)行訪問。不同的線程可以使用統(tǒng)一個對類,但是不用擔(dān)心這個隊列中的數(shù)據(jù)是否能夠同步,另外使用SizedQueue類能夠限制隊列的長度

SizedQueue類能夠非常便捷的幫助我們開發(fā)線程同步的應(yīng)用程序,應(yīng)為只要加入到這個隊列中,就不用關(guān)心線程的同步問題。

經(jīng)典的生產(chǎn)者消費者問題:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
#encoding:gbk
require "thread"
puts "SizedQuee Test"
 
queue = Queue.new
 
producer = Thread.new do
  10.times do |i|
    sleep rand(i) # 讓線程睡眠一段時間
    queue << i
    puts "#{i} produced"
  end
end
 
consumer = Thread.new do
  10.times do |i|
    value = queue.pop
    sleep rand(i/2)
    puts "consumed #{value}"
  end
end
 
consumer.join
 
程序的輸出:
SizedQuee Test
0 produced
1 produced
consumed 0
2 produced
consumed 1
consumed 2
3 produced
consumed 34 produced
 
consumed 4
5 produced
consumed 5
6 produced
consumed 6
7 produced
consumed 7
8 produced
9 produced
consumed 8
consumed 9

使用ConditionVariable實現(xiàn)同步控制

使用 ConditonVariable進(jìn)行同步控制,能夠在一些致命的資源競爭部分掛起線程直到有可用的資源為止。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#encoding:gbk
require "thread"
puts "thread synchronize by ConditionVariable"
 
mutex = Mutex.new
resource = ConditionVariable.new
 
a = Thread.new {
  mutex.synchronize {
    # 這個線程目前需要resource這個資源
    resource.wait(mutex)
    puts "get resource"
  }
}
 
b = Thread.new {
  mutex.synchronize {
    #線程b完成對resourece資源的使用并釋放resource
    resource.signal
  }
}
 
a.join
puts "complete"

mutex 是聲明的一個資源,然后通過ConditionVariable來控制申請和釋放這個資源。

b 線程完成了某些工作之后釋放資源resource.signal,這樣a線程就可以獲得一個mutex資源然后進(jìn)行執(zhí)行。 執(zhí)行結(jié)果:

?
1
2
3
thread synchronize by ConditionVariable
get resource
complete

線程類方法

完整的 Thread(線程) 類方法如下:


線程實例化方法

以下實例調(diào)用了線程實例化方法 join:

?
1
2
3
4
5
6
7
#!/usr/bin/ruby
 
thr = Thread.new do  # 實例化
  puts "In second thread"
  raise "Raise exception"
end
thr.join  # 調(diào)用實例化方法 join

以下是完整實例化方法列表:

初步講解Ruby編程中的多線程

初步講解Ruby編程中的多線程

以下實例調(diào)用了線程實例化方法 join:

?
1
2
3
4
5
6
7
#!/usr/bin/ruby
 
thr = Thread.new do  # 實例化
  puts "In second thread"
  raise "Raise exception"
end
thr.join  # 調(diào)用實例化方法 join

以下是完整實例化方法列表:

初步講解Ruby編程中的多線程

初步講解Ruby編程中的多線程

5

延伸 · 閱讀

精彩推薦
  • RubyCentOS中配置Ruby on Rails環(huán)境

    CentOS中配置Ruby on Rails環(huán)境

    經(jīng)過一個上午的折騰,終于把ROR環(huán)境在CentOS中搞定,繞了很多彎路,把文章寫下來總結(jié)一下 ...

    可樂加糖4762020-04-12
  • Ruby簡要說明Ruby中的迭代器

    簡要說明Ruby中的迭代器

    這篇文章主要介紹了Ruby中的迭代器,迭代器的概念在動態(tài)語言的編程中十分重要,文章中介紹了Ruby中的each迭代器和collect迭代器,需要的朋友可以參考下 ...

    goldensun2772020-04-25
  • RubyRuby環(huán)境下安裝使用bundler來管理多版本的gem

    Ruby環(huán)境下安裝使用bundler來管理多版本的gem

    這篇文章主要介紹了Ruby環(huán)境下安裝使用bundler來管理多版本的gem的方法,舉了Ruby On Rails中的應(yīng)用實例來進(jìn)行演示,需要的朋友可以參考下 ...

    日拱一卒4332020-05-10
  • Ruby剖析 Ruby 訪問控制

    剖析 Ruby 訪問控制

    前面,我們說 Ruby 沒有函數(shù),只有方法.而且實際上有不止一種方法.這一節(jié)我們介紹 訪問控制 (accesscontrols). 想想當(dāng)我們在最高層而不是在一個類的定義里定義...

    ruby教程網(wǎng)3572020-04-08
  • RubyRuby簡潔學(xué)習(xí)筆記(一):字符串、數(shù)字、類和對象

    Ruby簡潔學(xué)習(xí)筆記(一):字符串、數(shù)字、類和對象

    這篇文章主要介紹了Ruby簡潔學(xué)習(xí)筆記(一):字符串、數(shù)字、類和對象,本文是學(xué)習(xí)筆記第一篇,需要的朋友可以參考下 ...

    腳本之家2472020-04-20
  • RubyRuby進(jìn)行文件信息輸出實例代碼

    Ruby進(jìn)行文件信息輸出實例代碼

    Ruby進(jìn)行文件信息輸出實例代碼,數(shù)據(jù)是隨機(jī)的,所以每次的記錄都會不同。 ...

    ruby教程網(wǎng)2962020-04-10
  • RubyRuby設(shè)計模式編程中使用Builder建造者模式的實例

    Ruby設(shè)計模式編程中使用Builder建造者模式的實例

    這篇文章主要介紹了Ruby設(shè)計模式編程中使用Builder建造者模式的實例,建造者模式將一個復(fù)雜對象的構(gòu)造與它的表示分離,使同樣的構(gòu)建過程可以創(chuàng)建不同的表...

    范孝鵬2192020-05-07
  • RubyRuby迭代器的7種技巧分享

    Ruby迭代器的7種技巧分享

    這篇文章主要介紹了Ruby迭代器的7種技巧分享,Ruby中的迭代器非常人性化,本文既是講解了7個技巧也是講解了7種迭代器,需要的朋友可以參考下 ...

    腳本之家4782020-04-20
主站蜘蛛池模板: 国产成人高清亚洲一区91 | a男人的天堂久久a毛片 | 欧美亚洲桃花综合 | 操熟美女又肥又嫩的骚屁股 | 亚洲精品国产综合久久一线 | 手机在线观看网站免费视频 | 极品美女写真菠萝蜜视频 | 丫鬟粗大狠狠贯穿h | 高清视频在线播放 | free service性v极品 | 国产成人亚洲综合a∨婷婷 国产成人亚洲精品乱码在线观看 | 我与肥熟老妇的性事 | 精品无码乱码AV | 精品一区二区三区高清免费不卡 | porono日本动漫 | 亚洲第一综合天堂另类专 | 久久re这里精品在线视频7 | 亚洲美日韩 | 久久婷婷五月综合色丁香 | 久久se精品一区二区国产 | 大乳一级一区二区三区 | 国产精品边做边接电话在线观看 | 我半夜摸妺妺的奶C了她软件 | 国产精品香蕉夜间视频免费播放 | a一级毛片录像带 录像片 | 60岁了天天要小伙子 | 亚洲视频一区二区在线观看 | 色哟哟在线播放 | 午夜福利试看120秒体验区 | 欧美高清videosdesex0 | 男人午夜免费视频 | 97精品国产高清在线看入口 | 国产精品天天影视久久综合网 | 欧美一级片免费 | 日本韩国无矿砖码 | 日韩小视频在线观看 | 国产一卡二卡四卡免费 | 亚洲 欧美 国产 综合久久 | chinese国产打屁股 | 国内精品视频九九九九 | 国产欧美日韩亚洲精品区2345 |