3

私は posix スレッドを使用しています。私の質問は、スレッドが pthread_cancel 関数で独自のスレッド ID を渡すことによって自分自身をキャンセルできるかどうかです。はいの場合、その意味は何ですか

また、メイン プログラムが 2 つのスレッドを作成し、スレッドの 1 つが他のスレッドをキャンセルした場合、キャンセルされたスレッドの戻り値とリソースはどうなるか、どのスレッドがキャンセルされたかをメイン プログラムから知る方法は..どのスレッドもキャンセルしない

非同期キャンセルを使用しています

親切に助けて

4

3 に答える 3

7

Q1: はい、スレッドはそれ自体をキャンセルできます。ただし、これを行うと、一般的にキャンセルのすべてのマイナスの結果が生じます。おそらく代わりに使用したいと思うでしょうpthread_exit。これはやや予測可能です。

Q2: スレッドがキャンセルされた場合、戻り値を生成できません。代わりに、その引数が指す場所pthread_joinに特別な値を置きます。残念ながら、 を呼び出す前に、特定のスレッドが (何らかの方法で)確実に終了していることを別の方法で知る必要があります。そうしないと、呼び出し元のスレッドが永久にブロックされます。nor に相当する移植可能なものはありません。(マンページには、「この機能が必要だと思われる場合は、おそらくアプリケーションの設計を再考する必要があります」と書かれているため、誰かの顔を殴りたくなりました。)PTHREAD_CANCELEDretvalpthread_joinwaitpid(..., WNOHANG)waitpid(-1, ...)

Q2a: 「スレッドのリソース」の意味によって異なります。スレッド制御ブロックとスタックの割り当てが解除されます。pthread_cleanup_push登録されている、または実行されるすべてのデストラクタpthread_key_createが (スレッド上で、終了する前に); 一部のランタイムは、スタック上のオブジェクトに対して C++ クラス デストラクタも実行します。スレッドが所有するすべてのリソースがこれらのメカニズムのいずれかによってカバーされるようにするのは、アプリケーション プログラマの責任です。これらのメカニズムの一部には、固有の競合状態があることに注意してください。たとえば、ファイルを開いて、それを閉じるクリーンアップをアトミック アクションとしてプッシュすることはできないため、キャンセルすると開いているファイルがリークされる可能性があります。(ファイルを開く前にクリーンアップをプッシュすることでこれを回避できるとは思わないでくださいキャンセルは、システムコールが返されるたびにそれらをチェックすることです。つまり、OS がファイル記述子番号を戻り値レジスタに書き込んでから、呼び出し関数がそのレジスタをクリーンアップが期待するメモリ位置にコピーするまでの小さなギャップに到達する正確なタイミングです。となります。)

Qi: 質問していませんが、非同期キャンセルが有効になっているスレッドは、純粋な計算以外のことを公式に許可されていないことに注意してください。、、または以外のライブラリ関数を呼び出した場合の動作は未定義です。pthread_cancelpthread_setcanceltype(PTHREAD_CANCEL_DEFERRED)pthread_setcancelstate(PTHREAD_CANCEL_DISABLE)

于 2013-10-15T18:22:17.503 に答える
0

スレッドは、自分自身を含む他のスレッド (同じプロセス内) をキャンセルできます

スレッドには戻り値がありません (一般的に、戻りステータスのみを持つことができます)。スレッドのリソースはキャンセル時に解放されます。

メインプログラムはスレッドのハンドラーを保存し、それが有効かどうかをテストできます

于 2013-10-15T17:58:35.377 に答える