# 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}"