2

いくつかの検索手順が異なるスレッドに並列化されている状況があります。各スレッドは同じpymongo.cursor.Cusorオブジェクトを取得して結果を確認しますが、各スレッドは異なる処理を実行します。次のようなデモ手順を作成しました。

class SearchProcedure(Thread):

    weight = 0.1

    def __init__(self,weight=None):
        if weight:
            self.weight = float(weight)
        Thread.__init__(self)

    def start(self,query):
        self.query = query
        Thread.start(self)

    def run(self):
        if hasattr(self,'places'):
            for p in self.places.values():
                print p.name

        if hasattr(self,'posts'):
            for s in self.posts.values():
                s.rewind()
                print [(sh['name'],sh['description']) for sh in s]

    def attach_eligible(self,queue,**kwargs):
        self.queue = queue
        for (name,value) in kwargs.items():
            setattr(self,name,value)

このattach_eligibleメソッドでは、場所と投稿のプロパティをプロシージャオブジェクトに追加します。繰り返しになりますが、postsプロパティは反復可能なmongoカーソルのセットです。結果を実行するrewind前に、別のスレッドがすでにカーソルを巻き戻している場合は、カーソルを元の状態にリセットするために使用します。アイデアは、各スレッドが異なる基準を使用してオブジェクトを検索し、その結果をqueue呼び出し元/インスタンス化スコープで使用するためにプロパティに出力するというものです。

最初のスレッドは正常に実行されますが、後続のすべてのスレッドはカーソルを利用して次のエラーを出力します。

  File "/usr/local/lib/python2.7/dist-packages/pymongo/cursor.py", line 668, in __send_message
    assert response["starting_from"] == self.__retrieved
AssertionError

巻き戻しは、効果がないように思われます。これは、カーソルが参照によって渡されるためですか?ロックステータスを維持するために、それらもキューに含める必要がありますか?モンゴカーソルでこのようなことをすることさえ可能ですか?検索条件を同時に実行すると、検索条件の処理のパフォーマンスが大幅に向上するので、できれば便利です。

4

2 に答える 2

2

スレッド間で状態が変化するオブジェクトを自由に共有することは、それを許可するように特別に設計されていない限りできません。pymongocursorはこのために設計されていません。

できることは、カーソルのクローンを作成してから、各スレッドに独自のクローンコピーのカーソルを提供することです。を参照してくださいcursor.clone

于 2012-10-23T16:09:52.593 に答える
0

@JohnnyHKの答えを詳しく説明します:

この回答によると、カーソルはサーバーサイドにあります。実行されたインクリメント操作はサーバー側に反映されるため、2番目のスレッドでカーソルをコピーすることは(ある意味で)オブジェクト/オブジェクトのリストではなく、2番目のスレッドでURLをコピーすることに似ています。つまり、カーソルはデータベース内のデータへのポインタであり、サーバー側でコピーする以外はコピーできません。したがって、前述のように、cursor.cloneを使用する必要があります。

于 2020-09-03T08:06:50.263 に答える