あなたはfuture
への呼び出しをsequentializeしたい場合はこのように、手動でそれを使用することができます:彼らはまだ可能性の異なるスレッドで呼び出されるだろうが、次のものがまで呼び出されません
(do @(future 1)
@(future 2)
@(future 3))
前のことが終わった。これは、@
(またはderef
関数)によって保証されています。つまり、do
フォームを実行するスレッドは、完了する前にprev promiseでブロックされ、次に次のスレッドが生成されます。
あなたは、このようなマクロでそれを飾り立てることができます。
(defmacro sequentialize [& futures]
`(do [email protected](map #(list `deref %) futures)))
user> (let [a (atom 1)]
(sequentialize
(future (swap! a #(* 10 %)))
(future (swap! a #(+ 20 %)))
(future (swap! a #(- %))))
@a)
;;=> -30
これはマニュアルdo
とまったく同じことを行います。
user> (let [a (atom 1)]
(sequentialize
(future (Thread/sleep 100)
(swap! a #(* 10 %)))
(future (Thread/sleep 200)
(swap! a #(+ 20 %)))
(future (swap! a #(- %))))
@a)
;;=> -30
をなぜあなたは彼らだけが非同時に実行することを強制するために、同時実行のために設計されている構造を作成したいのでしょうか?既存のタスクがこのように定義されているか、通常は同時に実行されますが、限られた時間だけ順次実行する必要がありますか?ちょっと興味があるんだけど。 – Josh
一度に1つのスレッドだけが使用できる共有リソースXを使用するタスクを実行したいと望む複数のスレッド(たとえば、サーバー内の要求スレッド)があるとします。 1つの解決策は、Xにアクセスするたびにロックを取得することです。もう1つの方法は、Xに関連付けられた単一のスレッドで実行するタスク(先物)を送信することです。他の呼び出しスレッドは、将来の結果を待つかもしれません。 –
もちろん、この場合スレッドを作成するのはなぜですか?単なるスレッドから関数を呼び出すだけではどうですか? – Josh