You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Ruby Watir多线程控制同一浏览器实例报错及解决

解决Watir多线程操作浏览器时的read_nonblock/stream closed错误

我之前碰到过一模一样的问题:想在多线程里持续检查页面元素或操作Watir浏览器实例,结果频繁弹出read_nonblock和stream closed错误,网上搜了一圈也没找到明确的解释。后来才搞明白,这是因为多个线程同时访问同一个浏览器驱动实例,把底层的HTTP通信流给搞乱了——Watir/Selenium的浏览器对象本身就不是线程安全的,并发操作必然出问题。

复现问题的测试代码

下面这段代码会频繁触发错误,核心原因就是两个线程在没有任何同步机制的情况下,同时操作同一个browser对象:

require 'watir'
require 'thread'
profile = Selenium::WebDriver::Firefox::Profile.new
profile['permissions.default.image'] = 2
profile['media.autoplay.enabled'] = false
browser = Watir::Browser.new :firefox, profile: profile
threads = Array.new
threads[0] = Thread.new do
  loop do
    begin
      sleep(3)
      puts browser.url
      browser.goto("https://monip.org")
    rescue
      puts "thread 1 encountered an error"
    end
  end
end
threads[1] = Thread.new do
  loop do
    begin
      if browser.url == "https://monip.org"
        puts "hi"
      end
    rescue
      puts "thread 2 encountered an error"
    end
  end
end
threads.each do |e|
  e.join
end

解决方案:用Mutex实现线程同步

既然浏览器实例不是线程安全的,那我们就得保证同一时间只有一个线程能操作它。Ruby的Mutex(互斥锁)刚好能解决这个问题——把所有访问浏览器的代码都包裹在mutex.synchronize块里,这样同一时间只有一个线程能执行这些代码,从根源上避免并发冲突。

修正后的代码如下:

require 'watir'
require 'thread'
profile = Selenium::WebDriver::Firefox::Profile.new
profile['permissions.default.image'] = 2
profile['media.autoplay.enabled'] = false
mutex = Mutex.new
browser = Watir::Browser.new :firefox, profile: profile
threads = Array.new
threads[0] = Thread.new do
  loop do
    sleep(0.1)
    begin
      mutex.synchronize do
        puts "#{Time.now.ctime} #{browser.url}"
        browser.goto("https://monip.org")
      end
    rescue
      puts "#{Time.now.ctime} thread 1 encountered an error"
    end
  end
end
threads[1] = Thread.new do
  loop do
    sleep(0.1)
    begin
      mutex.synchronize do
        if browser.url == "https://monip.org/" || browser.url == "https://monip.org"
          puts "#{Time.now.ctime} hi"
        end
      end
    rescue
      puts "#{Time.now.ctime} thread 2 encountered an error"
    end
  end
end
threads[0].join
threads[1].join

运行效果

修正后的程序可以稳定持续运行,再也不会出现之前的错误,典型输出示例:

Fri Jan 5 13:49:36 2018 about:blank
Fri Jan 5 13:49:37 2018 hi
...

内容的提问来源于stack exchange,提问作者OmG3r

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 06:59:51