2016-05-03 10 views
4

私はそうのようなcore.async thread機能を作ってきたこのプロデューサ/コンシューマパターンを持っている:私はthreadためthe documentationを読んだときclojure core.asyncスレッドの中に `while true 'を入れるべきですか?

(defn -db-producer-factory [order-ids-chan next-chan] 
    (thread 
    (while true 
     (do 
     (let [order-id (<!! order-ids-chan)] 
      (condp = order-id 
      :finished (do 
         (>!! next-chan :finished)) 
      (supress-w-nextexc 
       (->> 
       ; get denorm'd order 
       (-> (r/-get-order :live order-id) 
        denorm/order->denormalized) 
       ; put in a map to avoid nils 
       (hash-map :data) 
       (>!! next-chan))))))))) 

はしかし、それは言う:

は、本体を実行します別のスレッドでは、すぐに 呼び出しスレッドに戻ります。完了時に 本文の結果を受け取るチャンネルを返します。

予想されるスレッドが1回限りと呼ばれるように聞こえます。ループ内にwhileループが構築されているわけではありません。

ブロック内にwhile trueを入れてはいけませんか?または、threadの結果を閉じるとスレッドがクリーンアップされますか?

答えて

1

スレッドが確実にクリーンアップされないため、おそらく、while trueループを使用しないでください。代わりに、終了条件付きのループを使用することができます。

一般的なパターンは、入力チャネルに応じて(他のスレッドで実行されるループを単純に言う)ことです。つまり、go -routineにデータを提供するチャネルが閉じられると、go-ルーチンがシャットダウンされます。私は、あなたのコードを少し書き換えおそらく何かを逃したが、私はあなたのアイデアを得るでしょう願っていました

(defn -db-producer-factory [order-ids-chan next-chan] 
    (go-loop [order-id (<! order-ids-chan)] 
    (condp = order-id 

     nil 
     ;; exiting 
     nil 

     :finished (do 
        (>! next-chan :finished) 
        (recur (<! order-ids-chan))) 
     (do 
     (supress-w-nextexc 
     (->> 
      (-> (r/-get-order :live order-id) 
       denorm/order->denormalized) 
      (hash-map :data) 
      (>! next-chan))) 
     (recur (<! order-ids-chan)))))) 

また、私はgo呼び出しでthreadコールを交換しました。これはネイティブスレッドをブロックする代わりにスレッドパーキングを使用する "軽量"バージョンのthreadです。 OSスレッドが必要な場合は、(thread (loop ...に置き換えることができます。

+0

私は 'スレッド'の中の 'loop'が/ disallocated/garbage collectの処理ができると信じていますが、あなたは私の質問に答えました! – Micah

+0

はそれをclojure#core-async slack roomで私のために解決しました。ありがとう! – Micah

0

ここでの議論を参照してください:http://www.braveclojure.com/core-async/

最も重要な文は次のとおりです。

あなたは 長時間実行中のタスクをされ実行しているとき、あなたが代わりに行くブロックのスレッドを使用する必要があります理由スレッドプールを詰まらせることはありません。

長時間実行されるタスクは、Javaスレッドが作成するものとまったく同じです。あなたは長期的な仕事をしているので(それは現れますか?)、自分のスレッドを持っているはずです。

JVMは、現代的なハードウェア上に問題のない1000個のユーザースレッドを処理できます。

+1

問題は、長時間実行されるスレッドがないことに関するものではありませんでした。それはもはや必要がなくなっても実行し続ける、長時間実行されるスレッドを持つことに関するもので、メモリリークを引き起こす可能性があります。 –

関連する問題