【问题标题】:Ruby, MongoDB: How to share a Cursor between threads?Ruby,MongoDB:如何在线程之间共享游标?
【发布时间】:2011-01-20 01:28:37
【问题描述】:

以下不起作用。线程内对 resources.next_document 的调用返回 nil。没有线程的相同调用按预期工作。

那里有 MongoDB 专家吗? :P

  resources = db[Resource::COLLECTION].find 

  number_of_threads.times do
    threads << Thread.new do
      while resource = resources.next_document
        puts 'one more doc'
      end
    end
  end  

【问题讨论】:

    标签: ruby multithreading mongodb


    【解决方案1】:

    虽然驱动程序本身是线程安全的,但个人游标不是,因此您无法以您描述的方式可靠地处理数据。

    一种可能性是让一个线程遍历文档,将它们交给任意数量的工作线程进行实际处理。

    【讨论】:

    • 有趣...如果光标在所有线程之间共享,为什么在线程生成之前或之后启动的查询会对光标产生不同的影响?
    • kb:看看我的回答,告诉我你的想法
    【解决方案2】:

    这是我最终使用的解决方案:

    欢迎反馈

    pool = DocumentPool.new(db)
    5.times do 
      Thread.new do
        while doc = pool.next_document
          #something cool
        end
      end
    end
    
    
    class DocumentPool   
      COLLECTION = 'some_collection'
    
      def initialize(db)
        @db = db                
        @first_doc = cursor.next_document      
      end
    
      def collection
        @db[COLLECTION]
      end
    
      def cursor
        @cursor ||= collection.find
      end   
    
      def shift
        doc = nil
        if @first_doc
          doc = @first_doc   
          @first_doc = nil  
        else
          doc = cursor.next_document    
        end
        doc
      end                               
    
      def count
        collection.count
      end
    end
    

    【讨论】:

    • 这在某些情况下可能有效,但我不相信它是万无一失的。为此,您需要围绕集合的 next_document 方法进行同步。
    • 为什么 next_document 方法需要同步,而我自己的“shift”方法不需要?
    • 我不确定这个@first_doc 是否有意义。所有这些转变所要做的就是围绕对 next_document 的调用进行同步。顺便说一句,在示例顶部的示例代码中,您调用 pool.next_document。我认为您的意思是 pool.shift。
    猜你喜欢
    • 1970-01-01
    • 2021-01-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-06
    • 2019-05-01
    • 2012-06-10
    相关资源
    最近更新 更多