【入門編】上級プロフェッショナル向け:VB.NETにおける「MemoryMappedFile」を活用したプロセス間通信:複数アプリ間で大容量データを数マイクロ秒で超高速共有するメカニズム – Visual Basic (VB / VB.NET)解析バイブル

スポンサーリンク

こんにちは!日々の開発、本当にお疲れ様です。
マクロの記録から一歩踏み出し、「もっと速く、もっとスマートにシステムを動かしたい!」と熱心に学んでいるあなたへ。今回は、VB.NETの底力を極限まで引き出す、ちょっとワクワクする技術のお話です。

「複数のアプリ間で、膨大なデータを一瞬でやり取りしたい」
そんな現場の切実な要望に直面したことはありませんか?

通常、プロセス間でデータをやり取りするには、ファイルを介したり、ネットワークソケット(TCP/IP)を使ったりします。でも、ギガバイト級のデータを数マイクロ秒で共有したいとき、それらの方法ではどうしても「遅延(ボトルネック)」が発生してしまいます。

そこで登場するのが、今回解説する `MemoryMappedFile`(メモリマップトファイル) です。
ここをクリアすれば、あなたのVB.NETスキルは間違いなく「上級プロフェッショナル」の領域に到達します。さあ、OSのメモリ空間を直接支配する裏技の世界へ、一緒に飛び込んでみましょう!

1. なぜ「MemoryMappedFile」なのか?(基本概念の理解)

まずは、イメージしやすいように身近な例で考えてみましょう。

  • 通常のファイル読み書き(手紙の郵送):

データを一度ハードディスクに書き込み、もう一つのアプリがそれを読みに行く方法です。確実ですが、ディスクへのアクセス(I/O)が発生するため、どうしても時間がかかります。

  • ソケット通信(電話での会話):

ネットワークを介してデータを送り合います。リアルタイムですが、通信プロトコルのオーバーヘッド(手続の重さ)がかかります。

  • メモリマップトファイル(同じ部屋の巨大なホワイトボード):

OSのメモリ上に「共有スペース」を作り、複数のアプリが同じホワイトボードを直接見に行く方法です。ディスクを挟まないため、物理的な限界に近いスピード(数マイクロ秒!)でデータが同期されます。

VB.NETでは、`System.IO.MemoryMappedFiles` ネームスペースを使うことで、この強力な仕組みを驚くほど簡単に実装できます。

2. 【実践】超高速プロセス間通信の実装コード

今回は、「書き込み側プロセス」「読み取り側プロセス」 の2つのサンプルを用意しました。
開発現場でそのままコピー&ペーストして実験できるように、丁寧なコメントを添えています。

① データを書き込む側のコード(Writer)

まずは、メモリ上に共有領域を確保し、そこにデータを高速で書き込むプログラムです。

Imports System.IO
Imports System.IO.MemoryMappedFiles
Imports System.Runtime.InteropServices

Module WriterProcess
Sub Main()
‘ 共有メモリの名前(一意の文字列)とサイズ(例: 1024バイト)を定義
Const mapName As String = “UltraFastIPC_Channel”
Const mapSize As Long = 1024

Console.WriteLine(“=== VB.NET メモリマップトファイル:ライター開始 ===”)

‘ 1. メモリマップトファイルを作成(存在しない場合は新規作成)
Using mmf As MemoryMappedFile = MemoryMappedFile.CreateOrOpen(mapName, mapSize)

‘ 2. メモリへのアクセサ(窓口)を取得
Using accessor As MemoryMappedViewAccessor = mmf.CreateViewAccessor()

‘ 送信したいデータ(例として文字列と数値を準備)
Dim message As String = “こんにちは、別プロセスからの超高速データです!”
Dim timestamp As Long = DateTime.Now.Ticks

‘ 3. データをメモリ上の指定アドレスに直接書き込む
‘ 最初の8バイトにタイムスタンプ、その後に文字列を書き込む設計にします
accessor.Write(0, timestamp)

‘ 文字列をバイト配列に変換して書き込み
Dim msgBytes As Byte() = System.Text.Encoding.UTF8.GetBytes(message)
accessor.Write(8, CUShort(msgBytes.Length)) ‘ 文字列の長さを記録
accessor.WriteArray(10, msgBytes, 0, msgBytes.Length)

Console.WriteLine(“データをメモリ空間に直書きしました!”)
Console.WriteLine(“[送信データ] ” & message)
End Using
End Using

Console.WriteLine(“書き込み側処理が完了しました。Enterキーを押すと終了します。”)
Console.ReadLine()
End Sub
End Module

② データを読み取る側のコード(Reader)

次に、先ほど書き込まれたメモリ空間から、一瞬でデータを吸い上げるプログラムです。

Imports System.IO
Imports System.IO.MemoryMappedFiles
Imports System.Text

Module ReaderProcess
Sub Main()
Const mapName As String = “UltraFastIPC_Channel”

Console.WriteLine(“=== VB.NET メモリマップトファイル:リーダー開始 ===”)
Console.WriteLine(“データを読み取ります…”)

Try
‘ 1. 既存のメモリマップトファイルを開く
Using mmf As MemoryMappedFile = MemoryMappedFile.OpenExisting(mapName)

‘ 2. 読み取り用のアクセサを開く
Using accessor As MemoryMappedViewAccessor = mmf.CreateViewAccessor(0, 1024, MemoryMappedFileAccess.Read)

‘ 3. メモリから直接データを読み出す
Dim timestamp As Long
accessor.Read(0, timestamp)

Dim msgLength As UShort
accessor.Read(8, msgLength)

Dim msgBytes(msgLength – 1) As Byte
accessor.ReadArray(10, msgBytes, 0, msgLength)

Dim message As String = Encoding.UTF8.GetString(msgBytes)
Dim sentTime As DateTime = New DateTime(timestamp)

‘ 結果表示
Console.WriteLine(“【データ受信成功】”)
Console.WriteLine(” 送信時刻: ” & sentTime.ToString(“HH:mm:ss.fffffff”))
Console.WriteLine(” 受信内容: ” & message)
End Using

End Using

Catch ex As FileNotFoundException
Console.WriteLine(“エラー: まだ書き込み側プロセスが実行されていないか、メモリ領域が存在しません。”)
Catch ex As Exception
Console.WriteLine(“予期せぬエラーが発生しました: ” & ex.Message)
End Try

Console.WriteLine(“読み取り側処理が完了しました。Enterキーを押すと終了します。”)
Console.ReadLine()
End Sub
End Module

3. 現場で陥りやすい罠とプロの回避術

この強力な `MemoryMappedFile` ですが、実務で使う際にはいくつか「知っておくべき罠」があります。ここがプロとアマの分かれ道です。

罠①:プロセスの終了タイミングとメモリの寿命

  • 現象: 書き込み側アプリを終了した瞬間、共有メモリが消えてしまい、読み取り側でエラーになる。
  • 解決策: `CreateOrOpen` で作成されたメモリは、最後のハンドルが閉じられるまでOS上に維持されますが、安全な運用のためには、「どのプロセスがデータのオーナー(管理者)か」を設計段階で明確にしておくことが重要です。

罠②:データ競合(レースコンディション)

  • 現象: 読み取り側がデータを読んでいるまさにその瞬間に、書き込み側が上書きしてしまい、データが文字化け(破損)する。
  • 解決策: 実業務で本格的なキューやリアルタイム通信を行う場合は、メモリマップトファイル単体ではなく、`System.Threading.Mutex`(ミューテックス)などの排他制御メカニズムを必ず組み合わせ、同時アクセスをガードしてください。

まとめ:VB.NETの可能性は、あなたの知識次第で無限に広がる

今回は、`MemoryMappedFile` を用いた超高速プロセス間通信のメカニズムを解説しました。

「たかがVB.NET、されどVB.NET」。
文法を覚えた次のステップとして、こうしたOSの低レイヤー(底面)の仕組みにアクセスできるようになると、作れるシステムの幅が一気に広がります。業務の自動化ツールや、複数連携する社内ニッチシステムのパフォーマンス問題に直面したとき、この知識が必ずあなたを救ってくれます。

「ここをクリアすれば、VB.NETの基本はバッチリですよ!」
ぜひご自身の環境でもコードを動かして、その圧倒的なスピード感を体感してみてください。あなたのエンジニアライフを、これからも心から応援しています!

タイトルとURLをコピーしました