MST
星途 面试题库

面试题:Ruby响应式编程与并发控制

在Ruby响应式编程中,当多个异步操作并发执行时,可能会出现数据竞争和不一致的问题。请设计一个复杂场景,其中包含多个并发的响应式操作,并展示如何使用Ruby的并发控制机制(如`Mutex`、`Semaphore`等)来确保数据的一致性和程序的正确性,要求写出完整且可运行的代码,并对关键部分进行详细注释。
34.2万 热度难度
编程语言Ruby

知识考点

AI 面试

面试题答案

一键面试
require 'async'
require 'mutex_m'

# 模拟一个数据库连接类,用于演示数据操作
class Database
  include Mutex_m

  def initialize
    @data = 0
  end

  # 增加数据的方法,需要线程安全
  def increment
    synchronize do
      @data += 1
      @data
    end
  end

  # 获取当前数据的方法,需要线程安全
  def get_data
    synchronize do
      @data
    end
  end
end

# 创建数据库实例
db = Database.new

# 使用async库来并发执行多个操作
Async do |task|
  # 创建多个并发任务
  10.times do |i|
    task.async do
      # 模拟异步操作,例如网络请求或其他耗时操作
      sleep(0.1)
      result = db.increment
      puts "Task #{i} incremented data to #{result}"
    end
  end

  # 等待所有任务完成
  task.wait

  final_data = db.get_data
  puts "Final data value: #{final_data}"
end

关键部分注释

  1. Database
    • include Mutex_m:混入Mutex_m模块,使得Database类可以使用synchronize方法来实现线程安全。
    • @data:模拟数据库中的数据,初始值为0。
    • increment方法:
      • synchronize do:使用synchronize块来确保在同一时间只有一个线程可以执行此块内的代码。这样就避免了数据竞争,保证每次只有一个线程能修改@data
      • @data += 1:增加数据的值。
      • @data:返回更新后的数据值。
    • get_data方法:
      • synchronize do:同样使用synchronize块,确保在读取数据时不会有其他线程修改数据,保证数据一致性。
      • @data:返回当前数据值。
  2. Async
    • 10.times do |i|:创建10个并发任务。
    • task.async do:每个任务在一个独立的线程中异步执行。
    • sleep(0.1):模拟异步操作的耗时,例如网络请求或复杂计算。
    • result = db.increment:调用Database实例的increment方法,由于increment方法是线程安全的,所以不会出现数据竞争。
    • puts "Task #{i} incremented data to #{result}":输出每个任务增加数据后的结果。
    • task.wait:等待所有异步任务完成。
    • final_data = db.get_data:获取最终的数据值。
    • puts "Final data value: #{final_data}":输出最终的数据值。