前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【Ruby高级技术】在项目中使用多线程之后的一系列问题解决方案-同步控制、异常处理、死锁处理

【Ruby高级技术】在项目中使用多线程之后的一系列问题解决方案-同步控制、异常处理、死锁处理

作者头像
上进小菜猪
发布2022-12-21 14:58:54
7800
发布2022-12-21 14:58:54
举报

多线程的运用

代码语言:javascript
复制
def func2
   j=0
   while j<=2
      puts "func2 at: #{Time.now}"
      sleep(1)
      j=j+1
   end
end

1.new可以用于创建线程,Thread也可以使用相同的语法Start或Thread。fork用于创建线程。 2.创建线程后,无需启动,线程将自动执行。 3.Thread类定义了一些处理线程的方法。线程执行thread.new中的代码块。 4.线程代码块中的最后一条语句是线程的值,它可以通过线程的方法调用。如果线程完成执行,则返回线程值;否则,在线程完成执行之前,不会返回该值。 5.线程。当前方法返回表示当前线程的对象。线main方法返回主线程。 6.通过Thread Join方法执行线程。此方法将暂停主线程,直到当前线程完成执行。

代码语言:javascript
复制
puts "Started At #{Time.now}"
t1=Thread.new{func1()}
t2=Thread.new{func2()}
t1.join
t2.join
puts "End at #{Time.now}"

系统上运行的每个程序都是一个进程。每个进程包含一个或多个线程。 线程是程序中的单序列控制流。在一个程序中同时运行多个线程以完成不同的工作称为多线程。 在Ruby中,我们可以通过Thread类创建多个线程。Ruby线程是轻量级的,可以以高效的方式实现并行代码。

代码语言:javascript
复制
def func1
   i=0
   while i<=2
      puts "func1 at: #{Time.now}"
      sleep(2)
      i=i+1
   end
end

线程发生异常

当线程发生异常且未被救援捕获时,通常会在没有警告的情况下终止线程。但是,如果其他线程由于thread#join关系一直在等待该线程,则等待线程也将抛出相同的异常。

代码语言:javascript
复制
begin
  t = Thread.new do
    Thread.pass 
    raise "unhandled exception"
  end
  t.join
rescue
  p $!  # => "unhandled exception"
end

主线程确实在等join。 使用以下三种方法,可以在线程因异常而终止时中断解释器。

  • 在启动脚本时指定-d选项,并在调试模式下运行它。
  • 使用Thread.art_on_exception设置标志。
  • 使用线程#abort_on_Exception设置指定线程的标志。

当使用上述三种方法之一时,整个解释器将被中断。

同步控制

在Ruby中,提供了三种同步方法: 1.通过Mutex类实现线程同步 2.用于监控数据切换的Queue类实现线程同步 3.使用ConditionVariable实现同步控制 通过Mutex类进行线程同步 Mutex类实现线程同步控制。如果同时需要多个线程时钟使用程序变量,则可以使用lock来锁定该变量。代码如下:

代码语言:javascript
复制
@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

除了使用锁锁定变量外,还可以使用try_lock锁定变量。您也可以使用Mutex.synchronize来同步对变量的访问。 用于监视数据切换的Queue类实现线程同步 Queue类表示支持线程并可以同步访问队列末尾的队列。不同的线程可以使用一对统一的类,但不要担心队列中的数据是否可以同步。此外,使用SizedQueue类可以限制队列的长度 SizedQueue类可以帮助我们非常方便地开发线程同步应用程序。只要我们加入这个队列,就不需要关心线程同步。

代码语言:javascript
复制
sleep 1
ticket1.join
ticket2.join

线程可以有自己的私有变量

线程可以有自己的私有变量,在创建线程时将其写入线程。它可以在线程范围内使用,但不能在线程外共享。 但有时,如果一个线程的局部变量需要由另一个线程或主线程访问呢?Ruby提供了按名称创建线程变量的能力,类似地将线程视为哈希表。通过[]=写入数据,通过[]读取数据。

代码语言:javascript
复制
count = 0
arr = []
 
10.times do |i|
   arr[i] = Thread.new {
      sleep(rand(0)/10.0)
      Thread.current["mycount"] = count
      count += 1
   }
end

线程的优先级是影响线程调度的主要因素。其他因素包括CPU的执行时间、线程分组调度等。 您可以使用线程。priority方法获取线程优先级和线程。priority=调整线程优先级的方法。 默认情况下,线程的优先级为0。优先级越高,执行速度越快。 一个线程可以访问其自身范围内的所有数据,但如果它需要访问线程中其他线程的数据。 Thread类为线程提供了一种访问彼此数据的方法。您可以简单地将线程用作哈希表。您可以使用[]=在任何线程中写入数据,使用[]读取数据。

代码语言:javascript
复制
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

死锁处理

当两个或多个计算单元正在等待对方停止运行以获取系统资源,但都没有提前退出时,这种情况称为死锁。 例如,进程p1占用显示器并且必须使用打印机,而打印机被进程p2占用并且p2必须使用显示器,这形成了死锁。 当使用Mutex对象时,我们需要注意线程死锁。

代码语言:javascript
复制
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"
   }
}

通常,正常的程序执行路径是单行执行。按编码顺序执行程序中的所有语句。然而,在多线程程序中,可以在多个路径中执行多个程序。多线程使用更少的内存空间并共享相同的地址空间。多线程用于同时执行多个任务。 创建线程后,无需启动线程。它在获得正确的CPU资源后自动运行。块中的最后一个表达式是线程的值。如果线程完全运行,value方法将返回线程值。否则,value方法将在线程完成时阻塞并返回。线程类在运行查询和操作线程时定义了一些方法。 通过调用线程的Thread.java方法。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2022-12-20,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 多线程的运用
  • 线程发生异常
  • 同步控制
  • 线程可以有自己的私有变量
  • 死锁处理
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档