共有メモリ
共有メモリは通常、プロセス間通信の最速の方法です。プロセス間で共有されるメモリ領域を提供します。1 つのプロセスがこの領域にデータを書き込み、別のプロセスがそれを読み取ることができます。
boost.interprocess では、共有メモリを表すためにクラス boost::interprocess::shared_memory_object が使用されます。このクラスを使用するには、ヘッダー ファイル boost/interprocess/shared_memory_object.hpp をインクルードします。
1 共有メモリの作成
例: 共有メモリの作成
#include <boost/interprocess/shared_memory_object.hpp>
#include <iostream>
using namespace boost::interprocess;
int main()
{
shared_memory_object shdmem{
open_or_create, "Boost", read_write};
shdmem.truncate(1024);
std::cout << shdmem.get_name() << '\n';
offset_t size;
if (shdmem.get_size(size))
std::cout << size << '\n';
}
boost::interprocess::shared_memory_object は 3 つのパラメーターを持つコンストラクターを使用します。
最初のパラメータは、共有メモリを作成するか、単に開くかを指定します。この例には、これら 2 つの状況、つまり boost::interprocess::open_or_create: 共有メモリがすでに存在する場合は共有メモリを開き、共有メモリが存在しない場合は共有メモリを作成することが含まれています。共有メモリを開くと、共有メモリが以前に作成されたことがわかります。
共有メモリを一意に識別するには、名前を割り当てます。
2 番目のパラメーターは、boost::interprocess::shared_memory_object の名前を指定します。
3 番目のパラメータは、プロセスが共有メモリにアクセスする方法を指定します。例 33.1 の boost::interprocess::read_write: は、プロセスが共有メモリへの読み取りおよび書き込みアクセス権を持っていることを示します。
boost::interprocess::shared_memory_object タイプのオブジェクトを作成すると、対応する共有メモリ ブロックがオペレーティング システムに存在します。このメモリ領域のサイズは、初期状態では 0 です。この領域を使用するには、truncate() を呼び出し、共有メモリのサイズをバイト単位でパラメータに渡します。この例では、共有メモリは 1,024 バイトのスペースを提供します。truncate() は、共有メモリが boost::interprocess::read_write モードで開かれている場合にのみ呼び出すことができます。そうでない場合は、例外 boost::interprocess::interprocess_Exception がスローされます。truncate() を繰り返し呼び出して、共有メモリのサイズを変更できます。
共有メモリを作成した後、メンバー関数 get_name() および get_size() を使用して、共有メモリの名前とサイズをクエリできます。
共有メモリは異なるプロセス間でデータを交換するために使用されるため、各プロセスは共有メモリをそのアドレス空間にマップする必要があります。これを行うには、クラス boost::interprocess::mapped_region が使用されます。つまり、共有メモリにアクセスするには 2 つが必要です (boost::interprocess::shared_memory_object と boost::interprocess::mapped_region)。これは、クラス boost::interprocess::mapped_region を使用して他のオブジェクトをプロセスのアドレス空間にマップできるようにするために行われます。
2 共有メモリをプロセスのアドレス空間にマップする
例: 共有メモリをプロセスのアドレス空間にマッピングする
#include <boost/interprocess/shared_memory_object.hpp>
#include <boost/interprocess/mapped_region.hpp>
#include <iostream>
using namespace boost::interprocess;
int main()
{
shared_memory_object shdmem{
open_or_create, "Boost", read_write};
shdmem.truncate(1024);
mapped_region region{
shdmem, read_write};
std::cout << std::hex << region.get_address() << '\n';
std::cout << std::dec << region.get_size() << '\n';
mapped_region region2{
shdmem, read_only};
std::cout << std::hex << region2.get_address() << '\n';
std::cout << std::dec << region2.get_size() << '\n';
}
クラス boost::interprocess::mapped_region を使用するには、ヘッダー ファイル boost/interprocess/mapped_region.hpp をインクルードします。
boost::interprocess::mapped_region クラスのコンストラクターの最初のパラメーターは boost::interprocess::shared_memory_object クラスのオブジェクトであり、2 番目のパラメーターはメモリ領域へのアクセスが読み取り専用であるか、読み取りおよび書き込みであるかを決定します。
例: boost::interprocess::mapped_region タイプの 2 つのオブジェクトが作成されます。Boost と呼ばれる共有メモリは、プロセスのアドレス空間にマップされます。mapped_region メンバー関数 get_address() および get_size() は、マップされたメモリ領域のアドレスとサイズを取得します。get_size() はどちらの場合も 1024 を返しますが、get_address() は異なる値を返します。
3 共有メモリへの書き込みと読み取り
例: 共有メモリへの書き込みと読み取り
#include <boost/interprocess/shared_memory_object.hpp>
#include <boost/interprocess/mapped_region.hpp>
#include <iostream>
using namespace boost::interprocess;
int main()
{
shared_memory_object shdmem{
open_or_create, "Boost", read_write};
shdmem.truncate(1024);
mapped_region region{
shdmem, read_write};
int *i1 = static_cast<int*>(region.get_address());
*i1 = 99;
mapped_region region2{
shdmem, read_only};
int *i2 = static_cast<int*>(region2.get_address());
std::cout << *i2 << '\n';
}
この例では、マップされたメモリ領域を使用して数値の書き込みと読み取りを行います。領域は、共有メモリの先頭に数値 99 を書き込みます。次に、Region2 は共有メモリ内の同じ場所を読み取り、その数値を標準出力ストリームに書き込みます。前の例の get_address() 戻り値で示されているように、region とregion2 はプロセス内の異なるメモリ領域を表しますが、両方のメモリ領域が基礎となる同じ共有メモリにアクセスできるため、プログラムは 99 を出力します。
4 共有メモリの削除
例:共有メモリの削除
#include <boost/interprocess/shared_memory_object.hpp>
#include <iostream>
using namespace boost::interprocess;
int main()
{
bool removed = shared_memory_object::remove("Boost");
std::cout << std::boolalpha << removed << '\n';
}
共有メモリを削除するために、boost::interprocess::shared_memory_object は、削除する共有メモリの名前をパラメータとして受け取る静的メンバー関数 Remove() を提供します。
Remove() が呼び出されない場合、プログラムが終了しても共有メモリは存在し続けます。共有メモリが自動的に削除されるかどうかは、基礎となるオペレーティング システムによって異なります。Windows および多くの UNIX オペレーティング システム (Linux を含む) は、システムが再起動されると共有メモリを自動的に削除します。
Windows は、それを使用する最後のプロセスが終了すると自動的に削除される特別な種類の共有メモリを提供します。boost/interprocess/windows_shared_memory.hpp の boost::interprocess::windows_shared_memory クラスにアクセスして、この共有メモリを使用できます。
5 Windows 固有の共有メモリの使用
例: Windows 固有の共有メモリの使用
#include <boost/interprocess/windows_shared_memory.hpp>
#include <boost/interprocess/mapped_region.hpp>
#include <iostream>
using namespace boost::interprocess;
int main()
{
windows_shared_memory shdmem{
open_or_create, "Boost", read_write, 1024};
mapped_region region{
shdmem, read_write};
int *i1 = static_cast<int*>(region.get_address());
*i1 = 99;
mapped_region region2{
shdmem, read_only};
int *i2 = static_cast<int*>(region2.get_address());
std::cout << *i2 << '\n';
}
boost::interprocess::windows_shared_memory はメンバー関数 truncate() を提供しません。代わりに、共有メモリのサイズを 4 番目のパラメータとしてこのクラスのコンストラクターに渡す必要があります。
boost::interprocess::windows_shared_memory クラスは Windows でのみ使用でき、移植性はありません。