私はFuture.rsを使用して、別のプロセスでいくつかのタスクを管理しようとしています。私は、それぞれの未来を待つ方法と、それを次々に処理する方法を見ていますが、その状態を知るために実行中の未来をポーリングすることはできませんでした。私はいつもエラーがあります:待つことなく未来の状態をポーリングする方法?
thread 'main' panicked at 'no Task is currently running'
私はいつもそれが完了するまで何かしたいです。おそらく私はそれを正しい方法で使っていないでしょうか?私はそれをチャンネルを使って動作させることができましたが、未来をポーリングして準備ができたら結果を得ることができるはずです。私はそれをテストするために使用 コードは次のとおりです。
fn main() {
println!("test future");
let thread_pool = CpuPool::new(4);
let mut future_execution_list = vec![];
let mutex = Arc::new(AtomicUsize::new(0));
//create the future to process
for _ in 0..10 {
let send_mutex = mutex.clone();
let future = thread_pool.spawn_fn(move || {
//Simulate long processing
thread::sleep(time::Duration::from_millis(10));
let num = send_mutex.load(Ordering::Relaxed);
send_mutex.store(num + 1, Ordering::Relaxed);
let res: Result<usize,()> = Ok(num);
res
});
future_execution_list.push(future);
}
// do the job
loop {
for future in &mut future_execution_list {
match future.poll() {
Ok(Async::NotReady) =>(), //do nothing
Ok(Async::Ready(num)) => {
//update task status
println!(" future {:?}", num);
}
Err(_) => {
//log error and set task status to err
()
}
};
}
//do something else
}
}
だから私はShepmasterの答えの後に私の質問を完了します。あなたの発言は非常に興味深いですが、私はまだ私の問題にsolutinを見つけることができません。私は自分の問題に関するいくつかの情報を追加します。私は一度にいくつかのタスクを管理できるオートメーション上でタスクをスケジュールしたい。イベントが管理され、タスクスケジューリングが計算されるループがあります。タスクがスケジュールされると、タスクが生成されます。タスクが終了すると、新しいスケジューリングが実行されます。タスクの実行中は、イベントが管理されます。 speudoのコードは次のようになります
loop {
event.try_recv() { ...} //manage user command for exemple
if (schedule) {
let tasks_to_spawn = schedule_task();
let futures = tasks_to_spawn.map(|task| {
thread_pool.spawn_fn(....)});
let mut one = future::select_all(futures);
while let Ok((value, _idx, remaining)) = one.wait() {..} //wait here
}
//depend on task end state and event set schedule to true or false.
}
私は将来的に共同スケジュールとタスクすることができますように:
let future = schedule.and_them(|task| execute_task);
しかし、私はまだ最初のタスクの実行の終了を待つ必要があります。 私はすべてを将来に置くことができます(イベント管理、スケジュール、タスク)、提案するように終了する最初のものを待ちます。私は試してみましたが、別のアイテムとエラーのタイプで未来のvecを作る方法を見ていませんでした。そして、この概念では、スレッド間でより多くのデータを管理する必要があります。イベント管理とスケジューリングを別のスレッドで実行する必要はありません。
別の問題があります。select_allはvecの所有権を持ちます。新しいタスクが他のタスクの実行中にスケジュールされなければならない場合、どのようにしてvecを変更して新しい将来を追加することができますか?
単純な解決策があるかどうかわかりません。私はisDone()のようなメソッドを使って、その実行中に未来の状態を待たずに得るのは簡単だと考えていました。おそらくそれは計画されている、私はそれについてのPRを見ていない。 シンプルなソリューションをお持ちでしたら、私の考え方を再考してください。
このように原子変数を使用したくない場合は99.9%です**。代わりに 'fetch_add'が必要です。大多数の人々は' Relaxed'の注文を望んでいません。 – Shepmaster
あなたの権利は、他の先物の実行に依存する将来の実行から結果を得たいということを示すために、いくつかのコードをコピー/ペーストするだけです。 –
あなたが回答を受け取った後、特に変更がそれらの回答を無効にしたときに、あなたの質問を変更することは非常に悪いフォームです*(http://meta.stackoverflow.com/q/309237/155423)。質問者は最初から関連する詳細を含む良い質問をすることが質問者にあります。 – Shepmaster