0

少し前に、ディスクからのサフィックス ツリーの保存/取得に関する質問を投稿しました。最終的にはうまくいきましたが、今は構築が非常に遅いので、今はウッコネンのアルゴリズム (線形構築) を台無しにしたくありません。

そのため、ツリーをスレッドセーフにすることなくプロセスを高速化するために、同時挿入を行いたいと考えました。

サフィックス ツリーは単語を最初の文字で格納します (私の前の質問に投稿された画像を見てください)。したがって、単語 Banana はルート ノードの 'B' 子にあり、Apple は 'A' 子などになります。 . したがって、'B' で始まる単語を挿入しても、'A' で始まる挿入が妨げられることはありません。私の考えは、挿入される一連の単語の最初の文字ごとにスレッドを作成することです。「A」を挿入するスレッド、「B」を挿入する別のスレッドなどです。

Executerだから私は、それぞれの単語のキューに単語を追加するだけ のクラスについて考えていましたProcess(存在しない場合は最初に作成してください)。

class Executer:
    #...
    def concurrent_insertion(word):
        k = word[0]
        processes.get(k, Process()).add(word)
    # ...

そして、クラスProcessは挿入を行うものです。各Processインスタンスは独立したスレッドであり、Queue挿入する単語が含まれています。

このProcessクラスでは、私が問題を抱えている場所です。threading.Thread各インスタンスはスレッドである必要があるため、から継承する必要があると思いますが、すべてのテキスト処理が完了するまでどうすればそれを維持できますか? つまり、その単語から単語を挿入する必要がQueueありますが、Queueが空の場合、スレッドが終了することはありません。さらに単語がいっぱいになるまで待ち続けてQueue、「目覚め」、挿入を続けます。

4

1 に答える 1

2

while Trueスレッドは終了するまで死ぬことはないので、ループ で生き続けることができます。

通常のパターンは次のようになります。

q = Queue.Queue()             # word insertion queue
terminate = object()          # sentinel value to tell a thread to terminate

def worker(q):
    while True:
         word = q.get()       # block until next word is available
         if word is terminate:
             break
         insert_word(word)

ワーカーを起動して単語をキューに送信した後、メイン スレッドはすべての作業が完了するまで待機する必要があり、その後ワーカーをシャットダウンする必要があります。

for word in wordlist:
    q.put(word)
for i in range(numthreads):
    q.put(terminate)          # terminate all the worker threads
for t in threadlist:
    t.join()                  # wait for them all to finish

すべての作業が完了するのを待つ別の方法は、q.task_doneandを使用することq.joinです。それらの使用方法の例は、Queue モジュールのドキュメントのページの下部に示されています。

于 2011-12-10T16:49:32.560 に答える