プロセスその22

そんなわけでVMS上ではかなり利用される事の多いMailboxであるが、なぜかWindowsではこれの移植は行われなかったようだ。理由としては、TCP/IPのために既にSocketを実装しており、これを流用すればよかったという事もあるが、これは後付け的な理由である。というのは、TCP/IPのSocketは、WindowsではWinsockと呼ばれるTCP/IP Stackが提供するSocket Serviceの形で実装されている。これはBSD UNIXのSocket Serviceをベースとしているが、細かく実装が異なっている上に、バージョンによって振る舞いが異なったりしているのは良く知られている。特にWinsock 1.xと2.xではだいぶ提供される機能が異なってきている。

更に言えば、Winsockはあくまでもネットワークサービスのものであり、ある程度高速化を図っているとはいえWindows Kernelの一部ではない。なので、例えばKernel Modeで動作しているProcess/Thread間の同期を取るためにはオーバーヘッドが大きく、適しているとは言えない。

もっと根本的な問題は、Windowsが既にEvent Objectを実装しており、これをベースとしてOSを構築することを目指していたためではないかと思う。もともとWindowsはMS-DOSの上に載る形でGUIを提供したものだが、Windowsの場合はMS-DOSと異なり、Application Logicの大半はCallback routineとして実装する形になるのが普通だ。従ってWindowsは、イベント(それはマウスボタンのクリックであったりポインタの移動であったり)の発生時にEventを発生させる→WindowsのEvent Dispatcherに飛び、ここで該当するEventに対するCallbackがあるか確認する→なければEvent Dispather終了。あればそのCallbackを呼び出す、という過程を猛烈な回数繰り返す事になる。

Windows 3.xとかWindows 9xでは、本質的な意味でのOSはMS-DOSであり、EventはあくまでWindowsという「皮」の中で利用されるものだったが、MS-DOSをベースとしないWindows NT系列では、このEventの処理を高速化してゆくために、OS自身でこれを管理する形にするのが一番賢明と考えたのであろう。実際例えばSetEvent()を見るとWinbase.h内で宣言され、ライブラリはKernel32.libとなっており、Windows Kernel自身でハンドリングされていることがわかる。

この結果、恐らくWindows上でEventを実行するコストは、ASTなどを使うVMSに比べてずっと下がったのだろうと思う。VMSの場合、CallbackはASTが事実上唯一の手段であったが、これは(そこそこに高速なものの)それなりに高コストの同期手段であり、だからこそEventFlagやMailboxが多用された側面がある。が、Eventのコストが下がったのであれば、そもそもOS LogicとかApplication LogicでCallbackを多用しているのだから、むしろ全てをEventを使ったCallbackで実装してしまったほうが話が楽である。

勿論Mailboxの持つメッセージ伝達に関してはEvent Objectではどうにもならない。そこで、WindowsではMailslotsと呼ばれるものが用意されていた。これを一言でまとめれば「VMSのMailboxの簡易版」というあたりか。つまりMailboxの同期機能はEvent Objectで代替できるので、これで代替できないものだけをMailslotsという名称で提供したという感じだ。

ただMailslotはDatagramを使ったBroadcastであり、最大424Bytes以下のメッセージを他のプロセスに伝達する、もっとも「簡易」な方法である。機構的には共有ファイルに近いもので、これをMemoryベースで実装したものであり、Domain全体に送信できるあたりはVMSのRemote Mailboxに近いものである。またMailslotの読み込み時のOVERLAPPERD structureの中にEventを指定することで、読み取り時にEventを発生させることも出来る。つまりMailboxの機能を同期とMessage伝達に分解し、前者はEvent Objectで代替して後者をMailslotに割り振った形だ。

そのMailslotだが、こちらを見ると"You can choose to use named pipes or Windows Sockets instead of mailslots for interprocess communications. "(プロセス間通信を行う場合、Mailslotsの代わりにnamed pipeやWindows Socketsを使うことができる)と遠まわしにMailslotの利用を薦めていないあたり、結果として大量のメッセージ交換をプロセス間で行う事が少ないと判断されたのではないか、と思われる。