著作一覧 |
って言うか、やっぱりCOMは好きだな。
バッドノウハウを愛でるのは、その蓄積が残念なことに自分を形成する一部になってるからかも。っていうか、バッドノウハウと言わずにプロトコルと言っておこう。
たとえば、TCP/IPな恋愛とUDP/IPな恋愛とIGMPな恋愛とか?
IGMPか……
Miguel de Icazaは日本での知名度はかなり低く、17.9%である。知名度が低いといっても5位だけど確かに低いのかな。
インターフェイス指向、言語透過指向とかいろいろおもしろいのでこんなのでもリンクしておくか。
ECMA標準の利用。Monoの開発動機とかについて語っている。
中田さんと青木さんの意見を取り入れた最終版。どうもありがとうございました。
追記:10:30より前のパッチとバイナリーは削除時に問題あります。もし、それより前にgetされた方は取り直してください。すみません。
#make時にコンパイルエラーになったのでチェックしたんだけど節穴になってたらしい。
うん? よく考えたらおいらのことなのかな?
確かにString s = new String("いつだって同じ文字列");
とか禁止したが。
確かにnew Boolean(true);じゃなくてBoolean.valueOf(true);使えと強要した覚えもあるが。
もうとっくに解決済みかも知れないけれど、.NETのオブジェクトのIDに何を使うか?の答えはObject.GetHashCode()だと思う。
根拠:
GetHashCode は、オブジェクトのどのインスタンスに対しても、常に同じ値を返す必要があります。 Object の派生クラスが値の等価を参照の等価として定義しており、値型以外の型である場合に限り、 GetHashCode は Object.GetHashCode 実装に処理を代行させることができます。
GetHashCode()には
GetHashCode の既定の実装では、一意性や一貫性は保証されません。したがって、ハッシュ用の一意オブジェクト識別子として使用しないでください。
という説明もありますが、一意性が保証されないのは、GCによって回収されたスロット(sscliでは同期処理用のインデックス。おそらく本物の.NETでも同様な同期処理用インデックスが必要なため同等と考えられる)に異なるインスタンスが格納される可能性があるからだと考えられます。しかし生存しているオブジェクト間に重複は論理的にありえないです。
なぜならそうでなければ、参照等価検査が正しく行われないことになり最初の引用が間違いということになってしまいます。
もちろん、以上のことは参照型だけに当てはまります。
ちなみに、sscliの実装は(Monoの開発に参加する気なら見ちゃだめですな)
[MethodImplAttribute(MethodImplOptions.InternalCall)]
public extern virtual int GetHashCode();
FCIMPL1(INT32, ObjectNative::GetHashCode, Object* objRef) {
..snip...
DWORD idx = objRef->GetSyncBlockIndex();
_ASSERTE(idx != 0);
..snip...
return idx;
}
FCIMPLEND
となっている。
追記:っていうかこれだけじゃだめで、
ulong id = (ulong)(o.GetType().GetHashCode() << 32 | o.GetHashCode());
としなければ、異なるクラスに属していたらアウト(かどうかまでは未調査)。
こいつが相変わらずパフォーマンスのことを書けるのは、まさにインテルとMSが処理速度を向上させているからだな。
まあ、1〜3は良い。というか1.は非常に良い。問題は4.だ。どうしてこうなるんだろう?
目的のSTAスレッドは,ほかの要求の処理のためにビジー状態になっていたり,ブロックされていたりする場合がある。この場合,クライアントと,要求を受け取ったスレッドは,そのスレッドを待っていなければならない。100個のスレッド,50個のCPUがあったとしても,たった1つのスレッドが使えるようになるまで待ち続けなければならないのである。
ユースケースの誤解はともかく、これは正しい。そこでプラットはMTAかNTAを使えと説教を垂れる。それはうまくやればそんなに間違いではない。しかし、
MTA,NAに住むオブジェクトは,Figure 7のようにCOM+カタログにエントリを作成することによって,同期サービスを必要とすることを宣言できる。こうすると,COM+は,サーバサイドのチャネルとスタブの間にポリシーオブジェクトを挿入する。このポリシーオブジェクトはミューテックスを使い,指定されたオブジェクトのメソッドにアクセスできるスレッドを1つだけに制限し,再入を適切に処理する。
はぁ?
100個のスレッド,50個のCPUがあったとしても,たった1つのスレッドが使えるようになるまで待ち続けなければならないのである。
だからSTA使うなと抜かした口はこの口か?
追記:そうか。COM+コンポーネントが100個くらいゲッタ/セッタを持ち、それを呼び出すというシナリオならばわからんでも無いかも。それならば同期不要なメソッドもたくさんあるかも知れない。でも普通はファサードを作るだろうし、最悪でもビジネスメソッドの外部公開にするよな。どうも、分散しているっていう意識が無いのだろうか?
#実は、そう単純ではない。再入の問題はびっくりするほどおもしろい。しかしプラットはそれについてはわかっていないのではないか?
ではどうするべきか? というと実はそのオブジェクトをどう使うかによって全然取るべき戦術が異なるんですな。でも基本は、Both + FreeThreadMarshalerでしょう。
追記:ふむNeutralを宣言するとGITへの登録が不要なのかな? それならNeutralのほうが良さそうだ。とは言うものの目に見えないオーバーヘッドはわからんし、ここでの話題はクリティカルなパフォーマンスチューニングの話なんだからMS謹製の枯れていない仕掛けに頼るデメリットはあるな。
5.以降はそんなに変じゃなさそうだ。しかし、4.についてこちらが見たのと同じような「はぁ」をそちらのジャンルの人が持つ可能性もあるだろうな。
実際問題としてプラットはコンポーネントやサービスを開発しているわけではなく、いわゆるソリューション屋さんだろう。そこが問題で、全然わかっていないのだと思われる。
アパートメントの実装を意識するのはコンテナだ。これはWindowsアプリケーションを開発する場合には重要なんだが、Windowを持てば否応なくSTAを利用することになる。現実として本当に意識する/しなければならないのは、IISのサブプロセスやスレッド(ISAPI DLLなど)あるいは、COM+コンテナやMTSコンテナの開発者ということになる。これは、ASPやASP.NETのアプリケーション開発者にとっては無関係(自分でどうこうできないこと。だってコンテナの中で動くコンポーネントを作るわけだから)なことだ。
アパートメントでの利用を意識するのはコンポーネント開発者だ。STA,MTA,Both,Both/FTM,Neutralのどのタイプで実装するかの決定権を持つ。
ビジネスロジックをアプリケーションコンポーネントとして開発する可能性はある。その場合、VB6ならば、これは否応なくSTAとなる。他の実装方法は無い。
.NETではじめてそれなりの自由度を持てる。っていうか、そのあたりをちゃんと調べてないな。ふむ。ASP.NETの場合はおいておこう。
ちなみにとりあえず、1番良いのは、STAで流すことなんだけどね。スレッディングをいじってどうにかしようというのは、最後の最後でしょう。しかも大体、不要。
追記:.NET Enterprise Services and COM+ 1.5 Architectureを後で読む。
COM Threading and Application Architecture in COM+ Applicationsを軽く読み返したがCOM+でのBoth/FTMの問題は大きそうだな。もう一度ちゃんと読んでおこう。
ジェズイットを見習え |