Ruby同步串行线程

时间:2014-08-07 07:20:42

标签: ruby multithreading synchronize

我通过Serial将数据发送到Arduino。我想构建错误检查,所以我不希望发送下一个命令,直到上一个命令“签出”。

在下面的伪代码中,我想阻止下一个命令.pop,直到process“释放”下一个命令。否则我想重试上一个命令。

理想情况下,锁定会在发送开始时发生。

class Arduino
  @threads = []

  def initialize
    # Connect to arduino serial
    @serial

    start_queues
  end

  def start_queues
    #read from serial
    @threads << Thread.new do
      while line = @serial.readline
        process(line)
      end
    end

    #pop from queue to send to Arduino
    @threads << Thread.new do
      loop do
        send(Queue.send_queue.pop)

        # Wait here until previous command completes properly
      end
    end
  end

  def process(data)
    # Check cmd
    # If success, 'send' next command
    # If error, requeue & 'send'
  end


  def send(data)
    @serial.write(data)
  end

end

1 个答案:

答案 0 :(得分:0)

使用MutexeConditionalVariable我可以锁定“发送”主题。

对于任何想要多线程的人来说,希望这会有所帮助:

class Arduino

  def initialize
    @threads    = []
    @work_queue = Queue.new
    @mutex      = Mutex.new
    @cmd_lock   = ConditionVariable.new
    @serial     = Queue.new

    # Connect to arduino serial
    start_queues
  end

  def start_queues
    #read from serial
    @threads << Thread.new do
      loop do
        process(@serial.pop)
      end
    end

    #pop from queue to send to Arduino
    @threads << Thread.new do
      loop do
        @mutex.synchronize do
          send(@work_queue.pop)

          @cmd_lock.wait(@mutex)
        end
      end
    end
  end

  def process(data)
    puts data

    # Check cmd
    if data == "example1"
      @cmd_lock.signal
    end
  end


  def send(data)
    @serial << data
  end

  def go
    puts "GO"
    @work_queue << "example1"
    @work_queue << "example2"
    @work_queue << "example3"

    @threads.each(&:join)
  end

end

Arduino.new.go