用 2 个线程控制同一个浏览器实例 WATIR RUBY

Controlling the same browser instance with 2 threads WATIR RUBY

我希望我的程序不断检查元素是否存在(始终检查它),但是当我尝试在另一个不同的线程中检查 HTML 时,我得到 read_nonblock 错误 and/or 流关闭错误(无法在互联网上找到解释) 所以我创建了这个程序来验证 wtf 是否正在发生。

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

我会

thread 1 encountered an error
thread 2 encountered an error
thread 2 encountered an error
thread 1 encountered an error
thread 1 encountered an error
about:blank
thread 2 encountered an error
thread 1 encountered an error
thread 1 encountered an error
thread 1 encountered an error
thread 2 encountered an error
thread 1 encountered an error
thread 2 encountered an error

当然,任何其他解决方案都会很好,这是我想到的但无法用代码编写.. 是否可以使程序 wait/check 如果它可以在浏览器中 control/communicate 一段时间。 或者为自己保留浏览器一段时间,我会使用 "sleep"。 或者允许 2 个线程同时控制浏览器。


编辑:我能够通过使用 "mutex"

获得所需的行为

这就是代码的样子

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
Fri Jan  5 13:49:37 2018  https://monip.org/
Fri Jan  5 13:49:37 2018  hi
Fri Jan  5 13:49:37 2018  https://monip.org/
Fri Jan  5 13:49:37 2018  hi
Fri Jan  5 13:49:37 2018  https://monip.org/
Fri Jan  5 13:49:38 2018  hi
Fri Jan  5 13:49:38 2018  https://monip.org/
Fri Jan  5 13:49:38 2018  hi
Fri Jan  5 13:49:38 2018  https://monip.org/
Fri Jan  5 13:49:38 2018  hi
Fri Jan  5 13:49:38 2018  https://monip.org/
Fri Jan  5 13:49:38 2018  hi
Fri Jan  5 13:49:38 2018  https://monip.org/
Fri Jan  5 13:49:39 2018  hi
Fri Jan  5 13:49:39 2018  https://monip.org/
Fri Jan  5 13:49:39 2018  hi
Fri Jan  5 13:49:39 2018  https://monip.org/
Fri Jan  5 13:49:39 2018  hi
Fri Jan  5 13:49:39 2018  https://monip.org/
Fri Jan  5 13:49:40 2018  hi
Fri Jan  5 13:49:40 2018  https://monip.org/
Fri Jan  5 13:49:40 2018  hi
Fri Jan  5 13:49:40 2018  https://monip.org/

正如您在时间戳中看到的那样,我们不断地分别检查而没有引发任何错误

你不能让他们同时使用浏览器。

问题 1:您的脚本永远不会输出 "hi",因为 url 实际上是“https://monip.org/", not "https://monip.org”。

问题 2:您可能想要 "constantly" 检查这个元素(我假设是某种对话之类的),因为一旦它出现,您就需要做一些事情。但是通过不断地检查,您实际上是在确保实际执行任务的线程将被中断。很可能每秒(甚至 2-10 秒)检查一次就足够了。

问题三:我一开始就说了,不能让他们同时使用浏览器。您需要实施某种锁定程序来防止这种行为。