std::async
ポリシーを使用して作成された非同期タスクを停止/キャンセルするにはどうすればよいstd::launch::async
ですか?つまり、futureオブジェクトを使用して、別のスレッドで実行されているタスクを開始しました。実行中のタスクをキャンセルまたは停止する方法はありますか?
3 に答える
要するにいいえ。
より長い説明:標準のC++ではスレッドをキャンセルする安全な方法はありません。これにはスレッドのキャンセルが必要になります。この機能はC++11の標準化中に何度も議論されており、一般的なコンセンサスは、そうするための安全な方法はないということです。私の知る限り、C++でスレッドキャンセルを行うために考えられる主な方法は3つありました。
スレッドを中止します。これはむしろ緊急停止のようなものです。残念ながら、スタックの巻き戻しやデストラクタの呼び出しは発生しません。スレッドは任意の状態にある可能性があるため、ミューテックスを保持している可能性があり、ヒープに割り当てられたデータがリークされる可能性があります。これは、プログラム全体が未定義になるため、明らかに長い間考慮されることはありませんでした。ただし、これを自分で行いたい場合は、それを使用
native_handle
してください。ただし、ポータブルではありません。強制キャンセル/中断ポイント。スレッドのキャンセルが要求されると、内部で変数が設定されるため、次に事前定義された一連の割り込みポイント(スリープ、待機など)が呼び出されたときに、例外がスローされます。これにより、スタックが巻き戻され、クリーンアップを実行できます。残念ながら、このタイプのシステムでは、ほとんどのマルチスレッドコードが突然スローされる可能性があるため、コードの例外を安全にすることは非常に困難です。
boost.thread
を使用したモデルです。これはdisable_interruption
、いくつかの問題を回避するために使用されますが、最も単純なケース以外の問題を正しく解決することは依然として非常に困難です。Boost.thread
このモデルを使用しますが、常に危険であると考えられており、当然のことながら、他のモデルと一緒に標準に受け入れられませんでした。自発的なキャンセル/中断ポイント。最終的に、これは、必要なときに自分で何らかの状態をチェックし、適切な場合は制御された方法で自分でスレッドを終了することになります。これを支援するためにいくつかのライブラリ機能を追加することについての話を漠然と思い出しますが、それは決して合意されませんでした。
たとえば、ラムダを使用している場合は、時々チェックできるアトミックな「キャンセル」変数を参照するのは非常に簡単です。
C ++ 11(私は思う)では、スレッドをキャンセルする標準的な方法はありません。std :: thread :: native_handle()を取得した場合、それを使用して何かを行うことができますが、それは移植性がありません。
多分あなたはいくつかの条件をチェックすることによってこのように行うことができます:
class Timer{
public:
Timer():timer_destory(false){}
~Timer(){
timer_destory=true;
for(auto result:async_result){
result.get();
}
}
int register_event(){
async_result.push_back(
std::async(std::launch::async,[](std::atomic<bool>& timer_destory){
while(!timer_destory){
//do something
}
},std::ref(timer_destory))
);
}
private:
std::vector<std::future<int>> async_result;
std::atomic<bool> timer_destory;
}