为什么实例变量在新线程中不起作用

时间:2015-03-08 16:19:27

标签: ruby multithreading arduino thread-safety

我很想进入多线程世界,我正在尝试构建一个在另一个线程上打开的运动检测器(这样我就可以继续处理我的主线程)。

def start_motion_detector
        # Create a new thread so that processes can run concurrently
        @thread = Thread.new do     

            # Connect to Arduino
            arduino = ArduinoFirmata.connect

            # Declare Pin 7 on the Arduino as an input pin
            arduino.pin_mode 7, ArduinoFirmata::INPUT

            # light = LifxInterface.new

            # Read the digital pins
            arduino.on :digital_read do |pin, status|
                # What to do if there is motion
                if pin == 7 && status == true
                    # light.turn_on
                    arduino.digital_write 13, true
                end

                # What to do if there is no motion
                if pin == 7 && status == false
                    # light.turn_off
                    arduino.digital_write 13, false
                end
            end
        end
    end

我遇到的问题是,当我将“arduino”作为一个局部变量留在我的新线程中时,此代码可以正常工作。但是,只要我在它前面放一个@,动作检测器就会完全停止工作。我想让它成为一个实例变量的原因是我想将配置步骤(连接到Arduino并设置输入引脚)拉出到初始化方法中。为什么会这样?

1 个答案:

答案 0 :(得分:1)

实例变量在新线程中有效。

我刚测试了你的代码(简化版),它就像一个魅力。你有另一个问题。也许你还没有替换所有的@或者你在其他地方使用@arduino并且它不是线程安全的。

def start_motion_detector
  @var = "hey"
  # Create a new thread so that processes can run concurrently
  @thread = Thread.new do
    puts @var
  end
end


start_motion_detector
gets.chomp

如果以前的代码不对您,请告诉我Ruby版本和修改后的代码。