このページの本文へ

Windows Info 第118回

RS4のWindows Subsystem for LinuxのAF_UNIXによるプロセス間通信

2018年02月25日 10時00分更新

文● 塩田紳二 編集● ASCII編集部

  • この記事をはてなブックマークに追加
  • 本文印刷

 Windows Insider Preview Build 17093より、Windows Subsystem for Linux(WSL)とWin32側でAF_UNIXによるプロセス間通信が可能になった。

 AF_UNIXは、バークレーSocketを使ったプロセス間通信でUnix由来の技術。AF_UNIXは「Unix Domain Socket」と呼ばれることもある。プロセス間通信とは、2つのプロセスの間でデータを交換できるようにすることである。一般にプロセス同士は仮想メモリにより独立したメモリ空間にあり、お互いに干渉できないようにしてセキュリティを高めている。APIレベルの話なので、本来ならここでコードを示して説明すべきだろうが、ここではコードを使わずに説明してみることにする。

WSLとWin32とでAF_UNIXを使ったプロセス間通信をするために
RS4に向けて、WSLのさまざまな改良が進められた

 AF_UnixをWin32側で扱うことは、すでにInsider Preview Build 17063で可能になっていた(本連載の第112回を参照のこと)。

 Build 17093では、WSL(側のLinux)とWin32側のプロセスでAF_UNIXを使ったプロセス間通信が可能になる。本連載でも解説してきたRS4のWSL改良点は、実はこれを実現するためのものだったのである。というのは、AF_UNIXでプロセス間通信を行なう場合、ファイルを共通のIDとして利用するからだ。

 一般にプロセス間通信をする場合、相手をどうやって指定するのか? というのが問題になる。たいていは、サーバー/クライアントモデルとなり、サーバー側は接続を待ち受け、クライアント側がサーバーを見つけて接続する。

 これが、ネットワーク(インターネット)を使った通信(ソケットにはIPによる通信AF_INETもある)なら、IPアドレス(とポート番号)を使うことができる。つまり、サーバを探す方法としてサーバに割り当てられたIPアドレスを使うわけだ。ただし、IPアドレス自体は、ウェブブラウザで人間がURLを指定するように、クライアントに対してユーザーが指定したり、クライアントに最初から組み込まれたドメイン名などを利用して接続する。見方を変えると、サーバはIPアドレスとポート番号という特定の「場所」で待っている。そこにクライアントが行って、通信をするということになる。

 プロセスは起動時にプロセス固有の番号(プロセスID)が割り当てられ、これで相手プロセスを区別することはできるが、プロセスIDは起動時に割り当てられるものなので、あらかじめ知ることができない。そのため、プロセスID以外の何らかのユニークな「待ち合わせ場所」が必要になる。

 ここで、待ち合わせ場所に適当なIDを使ってしまうと、他のソフトウェアと偶然同じになってしまう可能性がある。このため、システム内(プロセス間通信は1つのシステムで実行されているプロセス間に限られるためシステム内に限定される)で、同じものがない「ユニーク」な「待ち合わせ場所」が必要になる。

 たとえていうと、これは「君の名は」(アニメじゃないほう)と同じ状況。お互いの名前も知らない真知子と春樹は、半年後に銀座の数寄屋橋での再開を約束する話だ。真知子と春樹が2つのプロセスである。この2人が「会話」(プロセス間通信)するためには、「同じ場所」に行くしか方法がない。

 上の物語では、それが「数寄屋橋」なのである。そんなの携帯で連絡すればいいでしょ? というのは現在の話。この話は戦中のもので、携帯電話なんかなかったのだ。このため、待ち合わせをするのに事前に打ち合わせすることなどできないし、名前も知らないので手紙などどんな方法でも連絡が取れない状況なのである。互いに交わした「半年後に数寄屋橋で」という約束だけがある。プロセス間通信も同じで、通信するまでは、相手のプロセスがどれなのか、そもそも存在しているかどうかさえ、まったくわからないし、調べる方法もない。

 AF_UNIXでは、この待ち合わせ場所である「数寄屋橋」に相当するものとしてファイルを使う。ファイルは、常にシステムの中でユニークな存在である。このため、お互いに同じファイルを使うと開発時に決めておけば、2つのプロセスは、無事通信ができるようになるわけだ。一般的な手順としてAF_UNIXによるプロセス間通信に先立ち、ファイルを作る。通信が終了すれば、このファイルは削除する。

 AF_UNIXによるプロセス間通信では、ファイル名を共通のIDとして使うが、そのためには、ファイルに関する制御、たとえば書き込み許可や所有権などもWSL側から見て正しく動作しなければならない。

 無関係なプロセスに消されず、作成したプロセスが正しく削除できるためにもアクセス権の設定は重要になる。それが以前解説したDrvFsのmetadataである(本連載第114回、RS4におけるWindows Subsystem for Linuxの改良点)。これにより、DrvFsでもファイルの作成者やその所属グループと、それぞれの権限などが正しくファイルに反映される。

 もし2つの違うプログラムが、偶然、同じファイル名、同じディレクトリを指定していたとしても、先にソケットを作ったほうが有効で、後から同じファイルでソケットを作ろうとしたほうはエラーになる。少なくとも最初に起動したプログラムはうまく動き、2つ目はエラーになるが、エラーの原因はハッキリする。少なくとも衝突していることが検出できるなら、ユーザーがサーバークライアントともにファイルパスを指定するなど回避方法がある。

 また、metadataの導入に伴い、DrvFsのマウント方法を変更する必要があった。metadataは、あとから導入されたため、マウント時にオプションで指定する必要があったからだ。これを指定するのが前回解説したwsl.confだ(本連載第117回 RS4のWindows Subsystem for Linuxでのwsl.confによる初期設定)。

 さらにいえば、Win32とWSLがプロセス間通信を行うためには、WSL側のプロセスが動作している必要がある。そのために必要となったのがWSLのバックグラウンドタスクというわけだ(本連載第113回 Windows Subsystem for Linuxの起動とバックグラウンドタスク)。

 また、環境変数の共有(本連載第115回 RS4のWindows Subsystem for Linuxでは環境変数の共有が可能に)も、Win32とWSLで通信する場合のファイルパスをWin32とWSLの間で共有するために必要になる。

 ただし、これだけでは十分じゃない。というのは、Windowsでは、ファイル名の大文字小文字が区別されないのに対して、Linuxでは区別されている。つまり、WSL側では違うファイル(つまり別のプロセス間通信)と思っていても、大文字小文字の区別のないWin32側では、両者は同じファイルであり、そもそも大文字小文字しか区別のないファイル名を複数作ることができなかった。

 この大文字と小文字の区別に関しては、Build 17093で改良が加えられ、Win32側でフォルダごとに大文字小文字の区別「Case Sencitivity」を設定できるようになった。DrvFsを介して、WSLがWin32側のファイルシステムにディレクトリ(フォルダ)を作成すると、自動的に大文字小文字を区別するためのフラグが付加され、このフォルダ以下では、大文字小文字が区別されるようになる。

WSL側からDrvFs上にディレクトリを作成すると、大文字小文字を区別するフラグが設定され、Win32側ではそのフォルダでファイル名の大文字小文字が区別されるようになる

 ただし、AF_UNIXによるプロセス間コミュニケーションには、制限がある。DrvFs上に作られたファイルの場合、通信するプロセスは、WSL(Linux)側のプロセスとWin32側のプロセスに限定される。

 逆にVolFs(Linux側のネイティブなファイルシステム。Win32側からはアクセスができない)上のファイルを使う場合には、Linux内でのプロセス間通信になる。Win32側では、「afunix」と呼ばれるドライバー(Kernel Driver)が動作しており、これがWSL側とのプロセス間通信を行なっている。

AF_UNIXをWin32側で実現しているのはafunixと呼ばれるカーネルデバイスドライバ

 さて、RS4のWSLの改良点を見てきたが、AF_UNIXによるWin32とWSLの通信を可能にするために、WSL側の互換性(特にDrvFsの上での)を向上させるためにさまざまな改良がなされたことがわかる。また、マイクロソフトによれば、RS4ではWSLの起動速度も向上しているという。

 これで、WSLとWin32の間でAF_UNIXによるプロセス間通信が可能になったが、これは、APIレベルの話。これで何かができるのかというと、今後作られるプログラム次第である。Linux側には、AF_UNIXを使ってプロセス間通信をするアプリケーションは少なくないが、Win32側は現状何も存在していないといってもいい状態。

 おそらく、WSLの現時点での目標は、WSLでDockerなどを動かせるところまでWSLとネイティブ実行のLinuxの互換性を高めることだと思われる。その上でWin32相互運用性やAF_UNIXなどを使って、Win32とLinuxのソフトウェアを連携可能としていくのだろう。

カテゴリートップへ

この連載の記事

注目ニュース

ASCII倶楽部

プレミアムPC試用レポート

ピックアップ

ASCII.jp RSS2.0 配信中

ASCII.jpメール デジタルMac/iPodマガジン