MST

星途 面试题库

面试题:Ruby线程安全与同步机制之复杂场景处理

在一个Ruby多线程程序中,有多个线程需要读写一个复杂的数据结构(如嵌套的哈希表),并且要求尽可能提高并发性能,同时保证线程安全。除了Mutex,你还会考虑使用哪些同步机制?请阐述思路并给出关键代码片段。
23.9万 热度难度
编程语言Ruby

知识考点

AI 面试

面试题答案

一键面试
  1. 使用Monitor
    • 思路Monitor类提供了一种更高级的同步机制,它允许在一个对象上定义多个同步方法和临界区。相比于Mutex,它可以提供更细粒度的控制,并且可以在对象内部管理锁的状态,使代码结构更清晰。
    • 关键代码片段
require 'monitor'

class ComplexData
  include MonitorMixin

  def initialize
    @data = {}
    @monitor_enter
  end

  def read_data
    @monitor.synchronize do
      @data.dup
    end
  end

  def write_data(new_data)
    @monitor.synchronize do
      @data = new_data
    end
  end
end
  1. 使用ConditionVariableMutex配合
    • 思路:当一个线程需要等待某个条件满足时,ConditionVariable可以与Mutex协同工作。比如在更新复杂数据结构时,有些线程可能需要等待数据结构处于某种特定状态才能继续操作,ConditionVariable可以有效地管理这种等待和唤醒机制,从而提高并发性能。
    • 关键代码片段
require 'thread'

mutex = Mutex.new
cond = ConditionVariable.new
shared_data = {}

reader = Thread.new do
  loop do
    mutex.synchronize do
      while shared_data.empty?
        cond.wait(mutex)
      end
      data = shared_data.dup
      puts "Reader read: #{data}"
    end
  end
end

writer = Thread.new do
  loop do
    new_data = { key: 'value' }
    mutex.synchronize do
      shared_data = new_data
      puts "Writer wrote: #{new_data}"
      cond.signal
    end
    sleep 1
  end
end
  1. 使用Queue进行线程间通信
    • 思路:如果线程之间的数据交互可以通过队列来管理,那么可以将对复杂数据结构的读写操作封装在队列的处理逻辑中。Queue本身是线程安全的,通过将数据的生产和消费分离,不同线程可以通过队列来安全地访问和修改数据,从而提高并发性能。
    • 关键代码片段
require 'thread'

queue = Queue.new

producer = Thread.new do
  loop do
    data = { some: 'data' }
    queue << data
    sleep 1
  end
end

consumer = Thread.new do
  loop do
    data = queue.pop
    # 这里对数据进行处理,例如更新复杂数据结构
    puts "Consumer got: #{data}"
  end
end