マルチスレッドのプログラミング

取り消し

POSIX スレッドは、スレッドプログラミングに取り消し可能性 (取り消し機能) という考え方を導入しました。取り消し機能を使用することによって、スレッドはそのプロセスの他の任意のスレッドまたは全スレッドを終了させることができます。関連のある一群のスレッドの以降の操作がすべて有害または不必要な状況では、取り消しは 1 つの有効な方法です。好ましい方法は、すべてのスレッドを取り消し、そのプロセスを矛盾のない状態に戻してから起点まで戻ることです。

スレッドの取り消しの例としては、非同期的に生成される取り消し条件、たとえば実行中のアプリケーションを閉じるまたは終了するというユーザの要求などがあります。また、複数のスレッドが関わっているタスクの完了などもあります。最終的にスレッドの 1 つがそのタスクを完了させたのに、他のスレッドが動作し続けている場合は、その時点でそれらのスレッドは何の役にも立っていないため、すべて取り消したほうがよいでしょう。

取り消しには危険が伴います。そのほとんどは、不変式の復元と共有リソースの解放処理に関係します。不注意に取り消されたスレッドは mutex をロック状態のままにすることがあり、その場合はデッドロックを引き起こします。あるいは、どこか特定できないメモリー領域を割り当てられたままにすることもあるので解放できなくなります。

pthread ライブラリでは、取り消しをプログラムにより許可したり禁止したりする取り消しインタフェースを規定しています。ライブラリでは、どの点で取り消しが可能かを示す一群のポイント (取り消しポイント) も定義しています。さらに、取り消しハンドラ (クリーンアップサービスを提供する) の有効範囲を定義して、意図した時と場所に確実に働くようにできます。

取り消しポイントの配置と取り消しハンドラの効果は、アプリケーションに対する理解に基づくものでなければなりません。mutex は明らかに取り消しポイントではないので、ロックしている時間は必要最小限に留めるべきです。

非同期取り消しの領域は、宙に浮いたリソースや未解決の状態を生じさせるような外部に依存しないシーケンスに限定してください。入れ子の代替取り消し状態から復帰するときは、取り消し状態を復元するように注意してください。このインタフェースは、復元を容易に行えるように次の機能を提供しています。pthread_setcancelstate(3T) は、参照される変数の中に現在の取り消し状態を保存します。pthread_setcanceltype(3T) は、これと同じ方法で現在の取り消しタイプを保存します。

取り消しが起こりうる状況は、次の 3 通りです。

デフォルトでは、取り消しが起こりうるのは POSIX 規格で定義されているような、明確に定義されたポイントに限られます。

いずれの場合も、リソースと状態が起点と矛盾しない状態に復元されるように注意してください。

取り消しポイント

スレッドの取り消しは、取り消しが安全な場合にだけ行なってください。pthread 規格では、下記のような取り消しポイントが規定されています。

デフォルトでは、取り消しが有効 (使用可能) です。アプリケーションで取り消しを無効 (使用不可) にした場合は、再び有効にするまで、すべての取り消し要求が据え置かれます。

取り消しを無効にする方法については、「pthread_setcancelstate(3THR)」を参照してください。