Ruby多線程編程初步入門

來源:互聯網
上載者:User

Ruby多線程編程初步入門

   這篇文章主要介紹了Ruby多線程編程初步入門,線程是Ruby編程學習當中的重點和痛點,需要的朋友可以參考下

  傳統程式有一個單獨的線程執行,包含該程式的語句或指令順序執行直到程式終止。

  一個多線程的程式有多個線程的執行。在每個線程是按順序執行的,但是在多核CPU機器上線程可能並行地執行。例如,通常情況下在單一CPU的機器,多個線程實際上不是並存執行的,而是類比並行交叉的線程的執行。

  Ruby的可以使用 Thread 類很容易地編寫多線程程式。 Ruby線程是一個輕量級的和高效的在代碼中實現並行性。

  建立Ruby線程:

  要啟動一個新線程,關聯一個塊通過調用Thread.new。將建立一個新的線程執行的代碼塊,原始線程將立即從Thread.new返回並繼續執行下一個語句:

  ?

1

2

3

4

5

# Thread #1 is running here

Thread.new {

# Thread #2 runs this code

}

# Thread #1 runs this code

  例如:

  這裡是一個例子說明,我們如何能夠利用多線程的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}"

  這將產生以下結果:

  ?

1

2

3

4

5

6

7

8

Started At Wed May 14 08:21:54 -0700 2008

func1 at: Wed May 14 08:21:54 -0700 2008

func2 at: Wed May 14 08:21:54 -0700 2008

func2 at: Wed May 14 08:21:55 -0700 2008

func1 at: Wed May 14 08:21:56 -0700 2008

func2 at: Wed May 14 08:21:56 -0700 2008

func1 at: Wed May 14 08:21:58 -0700 2008

End at Wed May 14 08:22:00 -0700 2008

  線程的生命週期:

  建立一個新的線程用 Thread.new。也可以使用了同義字用 Thread.Start 和 Thread.fork。

  沒有必要啟動一個線程在它被建立後,它會自動開始運行時,CPU 資源成為可用。

  Thread 類定義了一些方法來查詢和處理的線程在運行時。運行一個線程塊中的代碼調用Thread.new,然後它停止運行。

  該塊中的最後一個運算式的值是線程的值,可以通過調用 Thread對象值的方法。如果線程運行完成,則該值為線程的傳回值。否則,該值方法會阻塞不會返回,直到該線程已完成。

  類方法Thread.current返回代表當前線程的 Thread對象。這允許線程操縱自己。類方法 Thread.main返回線程對象代表主線程,thread.this初始線程開始執行Ruby程式開始時。

  可以等待一個特定的線程通過調用該線程的Thread.Join方法來完成。調用線程將被阻塞,直到給定線程完成。

  線程和異常:

  如果在主線程中引發一個異常,並沒有任何地方處理,Ruby解譯器列印一條訊息並退出。在主線程以外的其他線程,未處理的異常導致線程停止運行。

  如果線程 t 退出,因為未處理的異常,而另一個線程調用t.join或t.value,那麼所發生的異常在 t 中提出的線程 s。

  如果 Thread.abort_on_exception 為 false,預設情況下,出現未處理的異常只是殺死當前線程和所有其餘的繼續運行。

  如果想在任何線程中的任何未處理的異常導致解釋退出中,設定類方法Thread.abort_on_exception 為 true。

  ?

1

2

t = Thread.new { ... }

t.abort_on_exception = true

  線程變數:

  一個線程可以正常訪問是在範圍內的任何變數的線程被建立時。一個線程塊的局部變數是線程的局部,而不是共用。

  Thread類提供一個特殊的功能,允許通過名稱來建立和存取線程局部變數。只需把線程對象,如果它是一個Hash,寫入元素使用[] =和讀取他們帶回使用[]。

  在這個例子中,每個線程記錄計數變數的當前值與該鍵mycount的一個threadlocal變數。

  ?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

#!/usr/bin/ruby

 

count = 0

arr = []

 

10.times do |i|

arr[i] = Thread.new {

sleep(rand(0)/10.0)

Thread.current["mycount"] = count

count += 1

}

end

 

arr.each {|t| t.join; print t["mycount"], ", " }

puts "count = #{count}"

  這將產生下面的結果:

  ?

1

8, 0, 3, 7, 2, 1, 6, 5, 4, 9, count = 10

  主線程等待子線程完成,然後列印出每個捕獲count的值。

  線程優先順序:

  影響線程調度的第一因素,是線程的優先順序:高優先順序線程之前計劃的低優先順序的線程。更確切地說,一個線程將只獲得CPU時間,如果沒有更高優先順序的線程等待運行。

  可以設定和查詢一個Ruby線程對象的優先順序=和優先順序的優先順序。新建立的線程開始在相同的優先順序的線程建立它。啟動主線程優先順序為0。

  沒有任何方法設定線程優先順序在開始運行前。然而,一個線程可以提高或降低自己的優先順序的第一次操作。

  線程排斥:

  如果兩個線程共用訪問相同的資料,至少有一個線程修改資料,你必須要特別小心,以確保任何線程都不能看到資料處於不一致的狀態。這稱為線程排除。

  Mutex類是一些共用資源的互斥訪問,實現了一個簡單的訊號鎖定。即,只有一個線程可持有的鎖在給定時間。其他線程可能選擇排隊等候的鎖變得可用,或者可以簡單地選擇立即得到錯誤,表示鎖定不可用。

  通過將所有訪問共用資料的互斥體的控制下,我們確保一致性和原子操作。我們的嘗試例子,第一個無需mutax,第二個使用mutax:

  無需Mutax的例子:

  ?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

#!/usr/bin/ruby

require 'thread'

 

count1 = count2 = 0

difference = 0

counter = Thread.new do

loop do

count1 += 1

count2 += 1

end

end

spy = Thread.new do

loop do

difference += (count1 - count2).abs

end

end

sleep 1

puts "count1 : #{count1}"

puts "count2 : #{count2}"

puts "difference : #{difference}"

  這將產生以下結果:

  ?

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

count1 : 1583766

count2 : 1583766

difference : 637992

 

#!/usr/bin/ruby

require 'thread'

mutex = Mutex.new

 

count1 = count2 = 0

difference = 0

counter = Thread.new do

loop do

mutex.synchronize do

count1 += 1

count2 += 1

end

end

end

spy = Thread.new do

loop do

mutex.synchronize do

difference += (count1 - count2).abs

end

end

end

sleep 1

mutex.lock

puts "count1 : #{count1}"

puts "count2 : #{count2}"

puts "difference : #{difference}"

  這將產生以下結果:

  ?

1

2

3

count1 : 696591

count2 : 696591

difference : 0

  處理死結:

  當我們開始使用互斥對象的線程排除,我們必須小心地避免死結。死結的情況發生時,所有線程正在等待擷取另一個線程持有的資源。因為所有的線程被阻塞,他們不能釋放其所持有的鎖。因為他們可以不釋放鎖,其它線程不能獲得這些鎖。

  一個條件變數僅僅是一個訊號,與資源相關聯,並用於特定互斥鎖的保護範圍內的。當需要一個資源不可用,等待一個條件變數。這一行動釋放相應的互斥鎖。當一些其他線程發送訊號的資源是可用的,原來的線程來等待,並同時恢複上的鎖臨界區。

  例子:

  ?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

#!/usr/bin/ruby

require 'thread'

mutex = Mutex.new

 

cv = ConditionVariable.new

a = Thread.new {

mutex.synchronize {

puts "A: I have critical section, but will wait for cv"

cv.wait(mutex)

puts "A: I have critical section again! I rule!"

}

}

 

puts "(Later, back at the ranch...)"

 

b = Thread.new {

mutex.synchronize {

puts "B: Now I am critical, but am done with cv"

cv.signal

puts "B: I am still critical, finishing up"

}

}

a.join

b.join

  這將產生以下結果:

  ?

1

2

3

4

5

A: I have critical section, but will wait for cv

(Later, back at the ranch...)

B: Now I am critical, but am done with cv

B: I am still critical, finishing up

A: I have critical section again! I rule!

  線程狀態:

  有五種可能的傳回值對應於下表中所示的5個可能的狀態。該的狀態方法返回的線程狀態。

  Thread類的方法:

  Thread類提供以下方法,它們適用程式的所有線程。這些方法它們使用Thread類的名稱來調用,如下所示:

  ?

1

Thread.abort_on_exception = true

  這裡是所有類方法的完整列表:

  線程執行個體方法:

  這些方法是適用於一個線程的一個執行個體。這些方法將被調用,使用一個線程的一個執行個體如下:

  ?

1

2

3

4

5

6

7

#!/usr/bin/ruby

 

thr = Thread.new do # Calling a class method new

puts "In second thread"

raise "Raise exception"

end

thr.join # Calling an instance method join

  這裡是所有執行個體方法的完整列表:

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

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.