我收到此错误: RuntimeError(在自动加载常量应用程序时检测到循环依赖性
当我多线程时。这是我的代码如下。为什么会这样? 我尝试多线程的原因是因为我正在编写一个HTML抓取应用程序。 对Nokogiri :: HTML(open())的调用是一个同步阻塞调用,返回需要1秒,我有100,000多个页面要访问,所以我试图运行几个线程来克服这个问题。有没有更好的方法呢?
class ToolsController < ApplicationController
def getWebsites
t1=Thread.new{func1()}
t2=Thread.new{func1()}
t3=Thread.new{func1()}
t4=Thread.new{func1()}
t5=Thread.new{func1()}
t6=Thread.new{func1()}
t1.join
t2.join
t3.join
t4.join
t5.join
t6.join
end
def func1
puts Thread.current
apps = Apps.order("RANDOM()").where("apps.website IS NULL").take(1)
while apps.size == 1 do
app = apps[0]
puts app.name
puts app.iTunes
doc = Nokogiri::HTML(open(app.iTunes))
array = doc.css('div.app-links a').map { |link|
url = link['href']
url = Domainatrix.parse(url)
url.domain + "." + url.public_suffix
}
array.uniq!
if (array.size > 0)
app.website = array.join(', ')
puts app.website
else
app.website = "NONE"
end
app.save
apps = Apps.order("RANDOM()").where("apps.website IS NULL").take(1)
end
end
end
答案 0 :(得分:8)
“require”不是线程安全的
更改您的方法,以便在线程开始之前完成所有“必需”的操作。
例如:
def get_websites
# values = Apps.all # try uncommenting this line if a second-try is required
ar = Apps.where("apps.website IS NULL")
t1 = Thread.new{ func1(ar) }
t2 = Thread.new{ func1(ar) }
t1.join
t2.join
end
def func1( ar )
apps = ar.order("RANDOM()").limit(1)
while (apps.size == 1)
puts Thread.current
end
end
但有人指出,不建议您在控制器中进行多线程处理。