适当的Mutex使用/良好的编码风格?

时间:2010-12-20 16:00:30

标签: ruby multithreading mutex multiprocessing

在以下代码中,生产者periodic_fill_page_queue可能会将页面添加到当前正在使用的队列中(读取:在设置状态being_processed之前的消费者中)。

class Example

  def initialize
    @threads      = ThreadGroup.new
    @page_queue   = Queue.new
    Thread.abort_on_exception = true
  end

  def start
    periodically_fill_page_queue
    periodically_process_page_queue
  end

  def periodically_fill_page_queue
    @threads.add(Thread.new do
      loop do
        if @page_queue.empty?
          Page.with_state(:waiting).each do |p|
            p.queued!
            @page_queue << f
          end
        end
        sleep 2
      end
    end)
  end

  def periodically_process_page_queue
    loop do
      until file = @page_queue.pop
        sleep 2
      end
      page.being_processed
      process(page)
    end
  end

  def process(page)
    sleep 120
    page.processed
  end

end


class Page < ActiveRecord::Base

  state_machine :state, :initial => :waiting do

    event :queued do
      transition :waiting => :queued
    end

    event :being_processed do
      transition :queued => :being_processed
    end

    event :processed do
      transition :being_processed => :processed
    end

  end

end

为避免这种情况,我会使用Mutex对象:

def initialize
  ...
  @mutex = Mutex.new
end

def periodically_process_page_queue
  loop do
    until file = @page_queue.pop
      sleep 2
    end
    @mutex.synchronize { page.being_processed }
    process(page)
  end
end

这是“好”的编码风格,还是有更优雅的方法?

谢谢!

1 个答案:

答案 0 :(得分:1)

不是这种设计。一些替代设计可能会做下面的一个,但自然有自己的蠕虫。

“叉”

对于每个工作,您开始一个新的线程或流程,为其提供工作

将任务委派给每个线程中的队列。每个线程都从自己唯一的队列中拉出来。

您有一个循环缓冲区,每个线程以不同的间隔进行检查。例如。 Num_threads + thread.id 这可能不适合你的情况。

范围

线程负责一系列工作。 num_threads * thread.id 这可能不适合你的情况。