Ruby 多線程

# Thread.new { do_some_thing}
# 建立線程以後線程會執行代碼塊中的東西
# 像處理圖片的話計算機CPU計算較多稱爲Compute-bound 上傳下載的話是IO-bound
# Multiprocess vs Multithread

def foo
  10.times do
    puts "call foo at #{Time.now}"
  end
  sleep(0.5)
end

def bar
  10.times do
    puts "call bar at #{Time.now}"
  end
  sleep(0.5)
end

p "*"*10 + 'start' + "*"*10
t1 = Thread.new { foo }
t2 = Thread.new { bar }
t1.join # join 主線程會在這等待 t1線程執行完畢後再往下執行
t2.join
p "*"*10 + 'end' + "*"*10

# Thread.current
# 每一個 Thread 都有本身的hash
count = 0
arr= []

10.times do |i|
  arr[i] = Thread.new do
    sleep(rand(0)/10.0)
    Thread.current["count"] = count
    count += 1
  end
end

arr.each do |t|
  t.join
  print t["count"], ","
end

puts "count = #{count}"

# Thread priority
# 線程的優先 priority 的值越大 越優先
count1 = count2 = 0
a = Thread.new do
  loop { count1 += 1}
end
a.priority = 1

b = Thread.new do
  loop { count2 += 1}
end
b.priority = -1

sleep 1
p count1
p count2

# Thread 中的異常
# 若是主線程再等待子線程 若是此時子線程發生異常則會上拋給主線程
# t1 = Thread.new do
#   puts "In new Thread"
#   raise "Exception from thread"
# end
# t1.join
# puts "not reached"

# 但若是主線程不等待的話 子線程就本身終止掉
# t1 = Thread.new do
#   puts "In new Thread"
#   raise "Exception from thread"
# end
# sleep 1
# puts "not reached"

# 但若是 Thread.abort_on_exception = true的話則無論主線程是否等待子線程的異常都會扔給主線程
# Thread.abort_on_exception = true
#
# t1 = Thread.new do
#   puts "In new Thread"
#   raise "Exception from thread"
# end
# sleep 1
# puts "not reached"

# Mutex
# count1 = count2 = 0
# difference = 0
# counter = Thread.new do
#   loop do
#     count1 += 1
#     count2 += 2
#   end
# end
# spy = Thread.new do
#   loop do
#     difference += (count1 - count2).abs
#   end
# end
# sleep 2
# puts "count1 : #{count1}"
# puts "count2 : #{count2}"
# puts "difference : #{difference}"

# Ruby的多線程不是真正的多線程,Ruby在處理IO的時候是沒有GIL鎖
# Jruby 可真正的實現多線程

mutex = Mutex.new

count1 = count2 = 0
difference = 0
counter = Thread.new do
  loop do
    mutex.synchronize do # 線程在執行這塊block 這個線程不會被其餘線程切換掉
        count1 += 1
        count2 += 2
      end
  end
end
spy = Thread.new do
  loop do
    mutex.synchronize do
        difference += (count1 - count2).abs
      end
  end
end
sleep 1
puts "count1 : #{count1}"
puts "count2 : #{count2}"
puts "difference : #{difference}"
相關文章
相關標籤/搜索