- ベストアンサー
プロセスのハンドルと識別子
エディットやボタンなどへのアクセスは、ウインドウハンドルを使ってそれらのオブジェクトにアクセスしているんだと考えられますが、 プロセスやスレッドにはハンドルと識別子の両方があるので、その違いが分かりません。 あるスレッドが動いていて、それを止める場合、そのスレッドのハンドルを使うのか識別子を使うのかが想像できるようになりたいのです。 プロセスを終わらせる関数を見つけ、その関数の引数の型を調べるのではなく、ハンドルと識別子の違いを理解して、それを想像する方法を教えてください。
- みんなの回答 (1)
- 専門家の回答
質問者が選んだベストアンサー
OSを限定しないと正確な説明はできないので、ここではWindowsを仮定します。(他のOSの場合は補足願います。) グラフィックオブジェクト(エディットやボタンなど)の「ハンドル」と、カーネルオブジェクト(プロセスやスレッド)の「ハンドル」にはいくつか大きな違いがあります。 【グラフィックオブジェクトのハンドルの性質】 ・1つのオブジェクトに1つのハンドル番号が割り当てられる ・ハンドル番号の割り当てがシステム全体で重複しない ・どのプロセスからも同じハンドル番号で同じオブジェクトを参照できる 【カーネルオブジェクトのハンドルの性質】 ・1つのオブジェクトに複数のハンドル番号を割り当てることができる ・同じハンドル番号でも別のプロセスでは別のオブジェクトを指しているかもしれない ・同じハンドル番号でも別のプロセスでは無効かもしれない 例えば、プロセスAでウィンドウを作成し、そのハンドルが0x15e8だったとします。このとき別のプロセスBでハンドル0x15e8のウィンドウを操作すると、同じウィンドウを操作することになります。 これに対して、プロセスAでスレッドを作成し、そのハンドルが0x2ab0だったとします。このとき別のプロセスBでハンドル2ab0のスレッドを操作しようとしても、それが可能だとは限りません。 プロセスBがプロセスAのハンドルを「継承」しているか、プロセスBがスレッドの「識別子(ID)」を取得し、そこからプロセスB内で有効なハンドルを取得すれば、プロセスAのスレッドを操作することができるようになります。前者の場合、プロセスAの中で使用していたスレッドのハンドルがそのまま使えますが、後者の場合は同じ「プロセスAのスレッド」に対して、異なる値を持つ「プロセスB内で有効なハンドル」を取得することになります。 カーネルオブジェクトのハンドルはプロセスごとに割り当てられるので、システム全体を通じてハンドルを一覧することは通常はできません。しかしプロセスとスレッドに限っては、システム全体を通じての一覧ができないと不便です。そのため、プロセスとスレッドには特別に、システム全体を通じて一意であることが保証されている「識別子」が用意されています。 この「識別子」はグラフィックオブジェクトのハンドルと似た性質があります。 【プロセス識別子・スレッド識別子の性質】 ・1つのオブジェクト(プロセスまたはスレッド)に1つの識別子が割り当てられる ・識別子の割り当てがシステム全体で重複しない ・どのプロセスからも同じ識別子で同じオブジェクトを識別できる なお、識別子はオブジェクトを「識別」する(例えばスレッドAとスレッドBが同じか違うかを判断する)ためには使用できますが、オブジェクトの状態を「参照」・「操作(変更)」する(例えばスレッドAを停止する)ためには使用できません。識別子は「どのオブジェクトであるか」という情報を提供するだけだからです。 それ以上の情報の取得やオブジェクトの状態の操作は、プロセスごとにその参照・操作が許されているかどうかの設定(セキュリティ設定)があり、その設定を確認するためにオブジェクトを「開いて」ハンドルを取得する必要があります。 オブジェクトを開いてハンドルを取得する際には「オブジェクトに対してどういう操作を行うか」を指定します。このときシステムは、指定された操作が許されているかどうかをチェックします。ハンドルが取得できれば、その操作を行う権限があるということになります。 ハンドルと識別子の違いはこんなところです。
お礼
内容が難しくてあんまり分かりませんでしたが知りたかったことはかなり分かりました。 ウインドウオブジェクトの変更はハンドルを使うけど、別プロセスのウインドウオブジェクトに触れる時は、ハンドルよりもグローバルな識別子を使って目的のウインドウオブジェクトか確認してからハンドルを使ってウインドに触れるんですよね。 CreateProcessの継承は、プロセスのハンドルのスコープの幅に関するもので、オブジェクトの性質を継承するようなJAVA感覚の継承とは違う内容のようですね。 ありがとうございました。