回答:
std::terminate()
どのスレッドからでも呼び出すことができ、参照しているスレッドは強制的に終了します。
~thread()
ターゲットスレッドのオブジェクト上で、そのオブジェクトに介入するjoin()
ことなくdetach()
、そのオブジェクト上で実行されるように手配できます。これは、オプション1と同じ効果があります。
例外をスローするデストラクタを持つ例外を設計できます。そして、強制的に終了する場合に、ターゲットスレッドがこの例外をスローするように調整します。これに関するトリッキーな部分は、ターゲットスレッドがこの例外をスローするようにすることです。
オプション1と2はプロセス内リソースをリークしませんが、すべてのスレッドを終了します。
オプション3はおそらくリソースをリークしますが、ターゲットスレッドが例外をスローすることに同意する必要があるという点で、部分的に協調的です。
C ++ 11(私が承知している)には、マルチスレッドプログラムの単一のスレッドを協調せずに(つまり、すべてのスレッドを削除せずに)削除する移植可能な方法はありません。そのような機能を設計する動機はありませんでした。
A std::thread
はこのメンバー関数を持っているかもしれません:
native_handle_type native_handle();
これを使用して、OS依存の関数を呼び出し、必要な処理を実行できる場合があります。たとえば、AppleのOSの場合、この関数は存在し、native_handle_type
ですpthread_t
。成功すると、リソースがリークする可能性があります。
std::terminate
静的デストラクタを呼び出したり、出力バッファをフラッシュしたりしないため、リソースが解放される順序は明確に定義されていません。また、データがユーザーに表示されたり、永続ストアに書き込まれたり、さらには一貫して完全。
exit()
またはabort()
全体的に同じ効果を呼び出すこともできます。
@ハワード・ヒンナントの答えは正確かつ包括的です。しかし、std::terminate()
(プロセス全体で)たまたま@AlexanderVXが考えていた「終了」と同じ名前(1スレッド)を持っているので、あまりに速く読むと誤解される可能性があります。
要約:「1つのスレッドを強制終了+強制的に(ターゲットスレッドは連携しない)+純粋なC ++ 11 =不可能」
std::terminate()
答えは古典的ないたずら好きなジンの話のようなものです。それは、OPの手紙への願いのすべてを満たしますが、おそらく彼の意図した方法ではありません。控えめなユーモアは私を笑わせました。:-)
この質問は実際にはより深い性質を持ち、一般的にマルチスレッドの概念をよく理解しているため、このトピックについての洞察が得られます。実際には、それらを使用しないよう警告せずに非同期でスレッドを強制終了する機能を提供する言語やオペレーティングシステムはありません。そして、これらのすべての実行環境は、開発者に強く助言するか、協調的または同期的なスレッド終了に基づいてマルチスレッドアプリケーションを構築することを要求します。この一般的な決定とアドバイスの理由は、それらすべてが同じ一般的なマルチスレッドモデルに基づいて構築されているためです。
マルチプロセッシングとマルチスレッディングの概念を比較して、2番目の概念の利点と制限をよりよく理解しましょう。
マルチプロセッシングは、オペレーティング環境全体がオペレーティングシステムによって制御される完全に分離されたプロセスのセットに分割されることを前提としています。プロセスは、プロセスのローカルメモリとプロセス内のデータ、およびファイル、ソケット、同期オブジェクトなどのすべてのシステムリソースを含む実行環境の状態を組み込み、分離します。分離は、プロセス境界による障害伝播を制限するため、プロセスの非常に重要な特性です。つまり、システム内の別のプロセスの一貫性に影響を与えるプロセスはありません。同じことがプロセスの動作にも当てはまりますが、制限が少なく、ぼやけた方法になります。このような環境では、最初に各プロセスが分離されるため、任意の「任意の」瞬間にプロセスを強制終了できます。次に、
対照的に、マルチスレッドは、同じプロセスで複数のスレッドを実行することを前提としています。ただし、このすべてのスレッドは同じ分離ボックスを共有しており、プロセスの内部状態をオペレーティングシステムで制御することはできません。その結果、どのスレッドもグローバルプロセスの状態を変更したり、破損したりできます。同時に、スレッドの状態がスレッドを強制終了しても安全であることがよく知られているポイントは、アプリケーションロジックに依存しており、オペレーティングシステムでもプログラミング言語ランタイムでも知られていません。その結果、任意の時点でスレッドが終了すると、実行パスの任意のポイントでスレッドが強制終了され、プロセス全体のデータの破損、メモリ、リークの処理に簡単につながる可能性があります。
このため、一般的なアプローチは、開発者に同期または協調スレッド終了を実装させることです。1つのスレッドが他のスレッド終了を要求し、明確なポイントの他のスレッドがこの要求をチェックして、明確な状態からシャットダウン手順を開始できます。すべてのグローバルシステム全体のリソースとローカルプロセス全体のリソースを安全かつ一貫した方法で解放します。
OS依存の関数を使用してC ++スレッドを終了するヒント:
std::thread::native_handle()
join()
またはを呼び出す前にのみ、スレッドの有効なネイティブハンドルタイプを取得できますdetach()
。その後、native_handle()
0を返します- pthread_cancel()
コアダンプします。
ネイティブスレッド終了関数(などpthread_cancel()
)を効果的に呼び出すには、std::thread::join()
またはを呼び出す前にネイティブハンドルを保存する必要がありますstd::thread::detach()
。そのため、ネイティブターミネーターは常に有効なネイティブハンドルを使用できます。
詳細については、http://bo-yang.github.io/2017/11/19/cpp-kill-detached-threadを参照してください。
強制終了する必要があるスレッドは、あらゆる種類の待機モードであるか、重い仕事をしていると思います。「素朴な」方法を使用することをお勧めします。
グローバルブール値を定義します。
std::atomic_bool stop_thread_1 = false;
スレッドが自然に終了するまで、コールスタック内のすべての関数が戻るように、次のコード(または同様のコード)をいくつかの重要なポイントに配置します。
if (stop_thread_1)
return;
次に、別の(メイン)スレッドからスレッドを停止するには:
stop_thread_1 = true;
thread1.join ();
stop_thread_1 = false; //(for next time. this can be when starting the thread instead)