ruby - 无法创建Thread(35)(ThreadError)

时间:2012-05-28 09:50:29

标签: ruby nokogiri

我对ruby很新,我正在学习如何在多个线程中进行处理。我所做的是使用Nokogiri解析170mb xml文件,我将数据库(Postgresql)插入我的.each()内的新线程中。请建议一个更好的方法来处理这个非常大的文件并在多个线程中执行它。这是我到目前为止所拥有的。

    conn = PGconn.connect("localhost", 5432, "", "", "oaxis","postgres","root")

    f = File.open("metadata.xml")
    doc = Nokogiri::XML(f)

    counter = 0

    threadArray = []

    doc.xpath('//Title').each do |node|
        threadArray[counter] = Thread.new{
        titleVal = node.text
        random_string = (0...10).map{ ('a'..'z').to_a[rand(26)] }.join

        conn.prepare('ins'+random_string, 'insert into sample_tbl (title) values ($1)')
        conn.exec_prepared('ins'+random_string, [titleVal])

        puts titleVal+" ==>"+random_string+ " \n"

        counter += 1
       }

    end

threadArray.each {|t| t.join}

f.close

1 个答案:

答案 0 :(得分:1)

与单线程情况相比,您正在执行的操作不会导致数据更快地插入数据库。 MRI Ruby具有全局解释器锁,并且一次只能运行一个线程。在MRI中使用线程Ruby仅在线程执行IO操作(或等待能够执行此操作)时提高性能,并且程序进度不依赖于这些IO操作的结果(因此您不会主动等待它们)。

我建议你在这里停止使用线程,而是计算你想要插入的所有值,并将它们大量插入。代码也将更容易理解和推理。即使从一个线程逐个插入它们也会更快,但没有理由这样做。