Ruby多线程

Ruby多线程

Ruby多线程教程,编程教程,例子教程,参考手册和代码 - 传统程序有一个执行线程,包括程序的语句或指令顺序执行,直到程序终止.

传统程序中有一个执行线程,包括程序的语句或指令顺序执行,直到程序终止.

一个多线程程序中有多个执行线程。在每个线程中,语句顺序执行,但可parallel.on执行线程本身多核的CPU,例如。多个线程往往在一个单CPU的机器,不实际执行并行,但并行交错执行的线程模拟.

Ruby可以很容易地写Thread类的多线程程序。 Ruby线程是一个轻量级的和有效的方式,以实现在你的代码的并行.

创建Ruby线程:

要开始一个新的线程,只是关联与以Thread.new调用块。将创建一个新线程执行的代码块,并从Thread.new原来的线程将立即返回,并恢复执行的下一条语句:

# Thread #1 is running here
Thread.new {
  # Thread #2 runs this code
}
# Thread #1 runs this code

例子:

这里是一个例子,它表明,我们可以使用多线程的Ruby程序.

#!/usr/bin/ruby
# by www.yiibai.com
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}"

这将产生以下结果:

Press ENTER or type command to continue
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对象代表主要thread.this. Thread.main是Ruby程序的开始,开始时的初始线程的执行.

你可以等待一个特定的线程通过调用该线程的Thread.join方法来完成。调用线程将阻塞,直到给定的线程完成.

线程和异常:

如果在主线程中,提出了一个异常没有被处理的任何地方,Ruby解释器打印一个消息,并退出。在主线程以外的线程,未处理的异常导致线程停止运行.

如果一个线程?退出,因为未处理的异常,而另一个线程s调用t.join或t.value,然后在T发生的异常提出在线程s.

如果Thread.abort_on_exception是假的,默认情况下,出现未处理的异常简单杀死(kill)当前线程和所有其余的继续运行.

如果你想在任何线程中任何未处理的异常导致退出该解释器,类方法Thread.abort_on_exception设置为true.

t = Thread.new { ... }
t.abort_on_exception = true

线程变量:

一个线程可以正常访问,线程被创建时该范围是任何变量。一个线程块的局部变量是线程局部的,不共享.

Thread类提供一个特殊的功能,允许通过名字创建和访问线程局部变量。您只需把线程对象,就好像它是一个Hash,写入元素使用[]=读取他们回到使用[].

在这个例子中,每个线程都记录在一个关键mycount ThreadLocal变量变量计数当前值.

#!/usr/bin/ruby
#by www.yiibai.com
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}"

这将产生以下结果:

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

主线程等待子线程完成,然后打印出每个捕获ofcount的值.

线程优先级:

影响线程调度的首要因素是线程的优先级:高优先级线程的低优先级线程之前预定。更确切地说,一个线程将只得到CPU时间,如果有没有更高优先级的线程等待运行.

你可以设置和查询与Ruby的Thread对象的优先级=和优先的优先级。新创建的线程开始创建它的线程的优先级相同。主线程在优先级0启动.

有没有办法设置一个线程的优先级之前开始运行。然而,一个线程可以提高或降低其作为第一项行动,它需要自己的优先级.

线程互斥:

如果两个线程共享相同的数据的访问,以及至少一个线程修改数据,你必须要特别小心,以确保没有线程所能看到的数据处于不一致的状态。这被称为线程互斥.

Mutex是一个类,它实现了一个简单的一些共享资源的互斥访问的信号锁定。也就是说,只有一个线程可以持有锁在一个给定的时间。其他线程可能会选择等待锁线,变为可用,或者可能干脆选择错误,指示立即得到锁不能使用.

通过将所有访问一个互斥的控制下共享数据,我们可以确保一致性和原子操作。让我们尝试的例子,第一个先不使用mutax而第二个使用mutax:

不使用Mutax例子:

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

这将产生以下结果:

count1 :  1583766
count2 :  1583766
difference : 637992

使用Mutax例子:

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

这将产生以下结果:

count1 :  696591
count2 :  696591
difference : 0

处理死锁:

当我们开始使用互斥对象的线程排斥,我们必须小心地避免死锁。死锁条件时所发生的所有线程正在等待获取另一个线程持有的资源。因为所有的线程被阻塞,他们不能释放持有的锁。因为他们不能释放的锁,没有其他线程可以获取这些锁.

这是条件变量的图片来。条件变量是一个简单的相关资源和用于特定互斥锁的保护范围内的信号。当你需要的资源是不可用的,你等待一个条件变量。这一操作释放相应的互斥锁。当其他一些线程信号的资源是可用的,原来的线程来等待,同时恢复对临界区锁.

例子:

#!/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! - by www.yiibai.com"
   }
}

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

这将产生以下结果:

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个可能的状态如下表所示。status方法返回线程的状态.

Thread state Return value
Runnable run
Sleeping Sleeping
Aborting aborting
Terminated normally false
Terminated with exception nil

线程类方法:

Thread类提供下列方法和适用程序中提供的所有线程。这些方法将被调用Thread类的名称,使用如下:

Thread.abort_on_exception = true

这里是所有类方法的完整列表:

SN Methods with Description
1 Thread.abort_on_exception
Returns the status of the global abort on exception condition. The default is false. When set to true, will cause all threads to abort (the process will exit(0)) if an exception is raised in any thread.
2 Thread.abort_on_exception=
When set to true, all threads will abort if an exception is raised. Returns the new state.
3 Thread.critical
Returns the status of the global thread critical condition.
4 Thread.critical=
Sets the status of the global thread critical condition and returns it. When set totrue, prohibits scheduling of any existing thread. Does not block new threads from being created and run. Certain thread operations (such as stopping or killing a thread, sleeping in the current thread, and raising an exception) may cause a thread to be scheduled even when in a critical section.
5 Thread.current
Returns the currently executing thread.
6 Thread.exit
Terminates the currently running thread and schedules another thread to be run. If this thread is already marked to be killed, exit returns the Thread. If this is the main thread, or the last thread, exit the process.
7 Thread.fork { block }
Synonym for Thread.new .
8 Thread.kill( aThread )
Causes the given aThread to exit
9 Thread.list
Returns an array of Thread objects for all threads that are either runnable or stopped. Thread.
10 Thread.main
Returns the main thread for the process.
11 Thread.new( [ arg ]* ) {| args | block }
Creates a new thread to execute the instructions given in block, and begins running it. Any arguments passed to Thread.new are passed into the block.
12 Thread.pass
Invokes the thread scheduler to pass execution to another thread.
13 Thread.start( [ args ]* ) {| args | block }
Basically the same as Thread.new . However, if class Thread is subclassed, then calling start in that subclass will not invoke the subclass‘s initialize method.
14 Thread.stop
Stops execution of the current thread, putting it into a sleep state, and schedules execution of another thread. Resets the critical condition to false.

线程实例方法:

这些方法适用于线程的一个实例。这些方法将被称为使用如下线程的一个实例:

#!/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 

这里是所有的实例方法的完整列表:

SN Methods with Description
1 thr[ aSymbol ]
Attribute Reference - Returns the value of a thread-local variable, using either a symbol or a aSymbol name. If the specified variable does not exist, returns nil.
2 thr[ aSymbol ] =
Attribute Assignment - Sets or creates the value of a thread-local variable, using either a symbol or a string.
3 thr.abort_on_exception
Returns the status of the abort on exception condition for thr. The default is false.
4 thr.abort_on_exception=
When set to true, causes all threads (including the main program) to abort if an exception is raised in thr. The process will effectively exit(0).
5 thr.alive?
Returns true if thr is running or sleeping.
6 thr.exit
Terminates thr and schedules another thread to be run. If this thread is already marked to be killed, exit returns the Thread. If this is the main thread, or the last thread, exits the process.
7 thr.join
The calling thread will suspend execution and run thr. Does not return until threxits. Any threads not joined will be killed when the main program exits.
8 thr.key?
Returns true if the given string (or symbol) exists as a thread-local variable.
9 thr.kill
Synonym for Thread.exit .
10 thr.priority
Returns the priority of thr. Default is zero; higher-priority threads will run before lower priority threads.
11 thr.priority=
Sets the priority of thr to an Integer. Higher-priority threads will run before lower priority threads.
12 thr.raise( anException )
Raises an exception from thr. The caller does not have to be thr.
13 thr.run
Wakes up thr, making it eligible for scheduling. If not in a critical section, then invokes the scheduler.
14 thr.safe_level
Returns the safe level in effect for thr.
15 thr.status
Returns the status of thr: sleep if thr is sleeping or waiting on I/O, run if thr is executing, false if thr terminated normally, and nil if thr terminated with an exception.
16 thr.stop?
Returns true if thr is dead or sleeping.
17 thr.value
Waits for thr to complete via Thread.join and returns its value.
18 thr.wakeup
Marks thr as eligible for scheduling, it may still remain blocked on I/O, however.
时间: 2024-11-05 15:48:32

Ruby多线程的相关文章

Ruby 多线程学习与实践

Ruby 多线程 每个正在系统上运行的程序都是一个进程.每个进程包含一到多个线程. 线程是程序中一个单一的顺序控制流程,在单个程序中同时运行多个线程完成不同的工作,称为多线程. Ruby 中我们可以通过 Thread 类来创建多线程,Ruby的线程是一个轻量级的,可以以高效的方式来实现并行的代码. 创建 Ruby 线程 要启动一个新的线程,只需要调用 Thread.new 即可: # 线程 #1 代码部分 Thread.new { # 线程 #2 执行代码 } # 线程 #1 执行代码 实例 以

雷林鹏分享:Ruby 多线程

Ruby 多线程 每个正在系统上运行的程序都是一个进程.每个进程包含一到多个线程. 线程是程序中一个单一的顺序控制流程,在单个程序中同时运行多个线程完成不同的工作,称为多线程. Ruby 中我们可以通过 Thread 类来创建多线程,Ruby的线程是一个轻量级的,可以以高效的方式来实现并行的代码. 创建 Ruby 线程 要启动一个新的线程,只需要调用 Thread.new 即可: # 线程 #1 代码部分 Thread.new { # 线程 #2 执行代码 } # 线程 #1 执行代码 实例 以

ruby多线程共享对象之线程安全

在进行多线程处理中共享对象,多个线程对同一个对象同时进行修改,有可能出现不一致的状态,使用时要注意. 例子: test.rb x = 0 10.times.map do |i| Thread.new do puts "before (#{ i }): #{ x }" x += 1 puts "after (#{ i }): #{ x }" end end.each(&:join) puts "\ntotal: #{ x }" 执行 rub

如何学习ruby?Ruby学习技巧分享

怎么学习ruby?在学习ruby之前需要掌握哪些知识呢?这是很多想要学习ruby朋友的心声,我不具体给出答案,下面就给大家讲讲一位前辈学习ruby(http://www.maiziedu.com/course/ruby/)的学习历程吧.在大学时学的电子专业,在学校里学过C/汇编,在学习ruby前期,和大多数的Rubyist一样,我也是从学习Rails开始去了解Ruby的,在学习Rails之前,我正在使用JavaEE的SSH框架(struts+spring+hibernate), 当时也算是Jav

Ruby 教程

Ruby 教程python-miniRuby 是一种开源的面向对象程序设计的服务器端脚本语言,在 20 世纪 90 年代中期由日本的松本行弘(まつもとゆきひろ/Yukihiro Matsumoto)设计并开发.在 Ruby 社区,松本也被称为马茨(Matz).Ruby 可运行于多种平台,如 Windows.MAC OS 和 UNIX 的各种版本.学习本教程,您将对 Ruby 有一个全面的了解.现在开始学习 Ruby!谁适合阅读本教程?本教程有助于初学者理解 Ruby 语言基础知识及基本概念.阅读

[汇]Ruby知识点(一)

1.介绍Ruby的多线程 Ruby的多线程是用户级多线程,这样使得Ruby的多线程移植非常容易,你并不需关心具体的操作系统:这样做也使线程容易控制,程序不容易产生死锁这类严重的线程问题.但是同时,由于Ruby的多线程并不是真正意义上的操作系统级多线程,不管代码使用了多少个Thread类的实例,都只会在启动解释器这一个进程内执行,由Ruby解释器进行具体的线程切换管理,其效率要低于由操作系统管理线程的效率,且不能使用多个CPU.在Ruby中同时做多件事最简单的方式就是使用Thread类,Threa

日志解析(二) 多线程http请求

发起http请求后,检查返回的数据是否含有特征码,几百w的数据跑了一天后也没跑完,尝试了下ruby多线程,发现并不能提高运行速度,果断换JAVA来写,ruby代码贴下: #coding:gbkrequire 'rubygems'require "net/http"require "uri"require 'zlib' threads = []    urls = IO.readlines "test.txt"    pFile = File.op

ruby中的多线程和函数的关键字传参

1.实现ruby中的多线程 # def test1 # n = 1 # if n > 10 # puts "test1结束" # else # while true # sleep 2 # puts n # n = n + 1 # end # end # end # # # def test2 # n = 100 # if n > 100 # puts "test2结束" # else # while true # sleep 2 # puts n #

Ruby之多线程

#Thread #1 is running here Thread.new{ #Thread #2 runs this code } #Thread #1 runs this code Thread.new的同义词是Thread.start和Thread.for 代码块中的最后一个表达式的值是线程的值,可以通过调用Thread对象的值的方法获得. Thread.current   表示当前线程的Thread对象. Thread.main 代表ruby程序的开始时的主线程 Thread.join