BoostIPC共有メモリ使用量の概要



Boost Ipc Shared Memory Usage Summary



BoostIPC共有メモリ使用量の概要

https://my.oschina.net/lday/blog/724458

http://zh.highscore.de/cpp/boost/interprocesscommunication.html



共有メモリ、プロセス間データ転送は1つの方法です。共有メモリへのデータ送信者データ、共有センス受信者からのメモリデータ内のデータ。これにより、データ全体の送信が完了します。 Linuxプラットフォームでは、オペレーティングシステムはユーザーに2つの共有メモリインターフェイスを提供します。

System-V共有メモリインターフェイス
int shmget(…) 共有メモリを作成する
int shmat(…) 共有メモリの接続
int shmdt(...) 共有メモリを切断します
int shmctl(…) 共有メモリオブジェクト情報を取得するには、共有メモリを削除します
Posix共有メモリインターフェイス
int shm_open(…) 共有メモリオブジェクトを作成または開く
int ftruncate(…) 共有メモリサイズを設定する
int fstat(…) 共有メモリオブジェクト情報を取得するには
Int shm_unlink(…) 共有メモリを削除する
void * mmap(…) 共有メモリオブジェクトはローカルプロセススペースにマップされます

Windowsプラットフォームでは、オペレーティングシステムはユーザーに共有メモリインターフェイスを提供します。



Windowsプラットフォームの共有メモリインターフェイス
HANDLE CreateFileMapping(…) 共有メモリを作成する
HANDLE OpenFileMapping(…) 共有メモリの接続
void * MapViewOfFile(…) ローカルプロセススペースにマップされた共有メモリ
void UnmapViewOfFile(…) 共有メモリを解放します
void CloseHandle(…) 共有メモリマップトファイルハンドルを閉じる

プラットフォームが異なれば、使用する共有メモリインターフェイスも異なります。 C ++ Boostライブラリと共有メモリインターフェイスは、2種類のプラットフォームを使用して、さらなる抽象化とカプセル化を提供し、その部分をプロセス間関数ライブラリに配置します。プロセス間ライブラリの完全な説明は、次を参照できます。http://www.boost.org/doc/libs/1_57_0/doc/html/interprocess.html

ここでは、ブースト::プロセス間share_memoryの使用シナリオを簡単に要約します。

共有メモリプールが作成された後、共有メモリプールに基づいてオブジェクトを作成できます。共有メモリプールに既知/未知のオブジェクトを作成できます。



1.よく知られているオブジェクト、添付ファイルを作成し、削除します

既知のオブジェクトを作成する場合、オブジェクトは指定されたオブジェクト名を割り当てる必要があります

//bip::managed_shared_memory segment // Create a well-known objects MyType *instance = segment.construct ('MyType instance') //name of the object (0.0, 0) //ctor first argument

共有メモリオブジェクトを作成する利点はわかっています。他のプロセスは、同じ共有メモリプール、オブジェクトへの便利な場所に基づいて、オブジェクトの名前にすることができます。対応する必要な共有メモリオブジェクトにアタッチされた名前付きオブジェクトは、次の方法で指定された共有メモリプールを検索するだけです。

//bip::managed_shared_memory segment // well-known objects attached typedef std::pair ResultT ResultT res = segment.find('MyType instance') if (!res.second) { cout << 'could not find MyType instance' << endl }

有名なオブジェクトを削除します。destroyInterfaceを呼び出して完全に削除します。

//bip::managed_shared_memory segment // delete famous objects segment.destroy('MyType instance')

オブジェクトの作成、使用、破壊2.匿名

2.1オフセットポインタを使用した共有データに基づく

実際、ほとんどの場合、既知のオブジェクトを使用するつもりはありませんが、現時点では名前のないオブジェクトを使用するため、提供されている匿名オブジェクトの共有メモリプールを使用して共有メモリオブジェクトを作成する必要があります。

//bip::managed_shared_memory segment // create anonymous objects MyType *ptr = segment.construct(bip::anonymous_instance) (par1, par2...)

匿名オブジェクトは名前の配置で指定できないため、匿名オブジェクトAの共有メモリプロセスによって書き込まれる場合、プロセスBはそれを共有メモリに直接取得して使用することはできません。 Boost :: interprocessは、プロセスBが匿名オブジェクトのコンテンツを取得できるようにするメソッドを提供します。具体的には、boost :: interprocess :: offset_ptrを使用します。 offset_ptrをポイントすることにより、共有メモリ、共有メモリオブジェクトに匿名の共有メモリオブジェクトを作成します。プロセスAからプロセスB、プロセスBに送信されたOffset_ptrと、offset_ptrによって読み取られた実際のコンテンツ。 offset_ptrを指すオブジェクトは共有メモリに配置されているため、対応するオブジェクトが共有メモリからメモリを割り当てる機能を備えている必要があります。これは、対応するチャネルの共有メモリアロケータを指すオブジェクトであるメモリアロケータです。

#include #include #include namespace bip = boost :: interprocess // to set the alias ipc // First define the type of shared memory allocator typedef bip::allocator CharAllocator typedef bip::basic_string shared_string struct IPCData { shared_string name int id boost::atomic atomicShrMmOrderRefCnt IPCData(const shared_string::allocator_type& al):name(al),atomicShrMmOrderRefCnt(1) { id = 0 } } // define data OffsetPtr typedef bip::offset_ptr IPCDataOffsetPtrT // define the offsetPtr memory allocator typedef bip::allocatorIPCDataOffsetPtrAllocatorT

後に対応するオフセットアドレスポインタを定義すると、匿名の共有メモリオブジェクトを作成でき、オフセットへの共有メモリオブジェクトポインタをホストします。

//bip::managed_shared_memory segment // Create an anonymous shared memory pointer offset_ptr IPCDataOffsetPtrT ipcDataOffsetPtr = segment.construct(bip::anonymous_instance) (shared_string::allocator_type(segment.get_segment_manager()))

それ以降、対応する共有メモリチャネルを定義して、プロセスAがチャネルにoffset_ptrするようにします。

#include namespace bip = boost :: interprocess // to set the alias ipc // definition is based on the offsetPtr dispenser and the corresponding memory queue typedef bip::list IPCDataOffsetPtrQueueT //bip::managed_shared_memory segment //ipcDataOffsetPtr // find the corresponding allocator const IPCDataOffsetPtrAllocatorT alloc_inst(segment.get_segment_manager()) IPCDataOffsetPtrQueueT *pIPCDataOffsetPtrQueue pIPCDataOffsetPtrQueue = segment.construct (channelName.c_str())(alloc_inst) pIPCDataOffsetPtrQueue->push_back(ipcDataOffsetPtr )

チャネルからデータを読み取るプロセスBによって:

//bip::managed_shared_memory segment //ipcDataOffsetPtr ipcDataOffsetPtr = pIPCDataOffsetPtrQueue->front() IPCDataOffsetPtrQueue->pop_front() cout

匿名共有メモリオブジェクトの使用が終了すると、共有メモリプールdestroy_ptrを介して完全なメモリが解放されます。

共有メモリに基づく2.2はデータ使用量を処理します

匿名オブジェクトを使用するには、プロセス間のブリッジとしてoffset_ptrが必要であり、2つのプロセス間の送信はoffset_ptrであり、その後、offset_ptrに対応する共有メモリオブジェクトを介して間接的に取得されます。この方法はデータ共有の目的を達成できますが、2つの欠点があります:1)この方法は少し周りに見え、直感的ではありません2)配信方法が変更されているため、単純なタイプ(POD)ではないオフセットポインタを使用しない送信キューを後押しするものはありません。プロセス間でデータを共有するためのより便利な方法を使用できるようにするためのより簡単な方法はありますか?答えは次のとおりです。はい:: managed_shared_memory ::ブーストによる処理::プロセス間。ハンドルを使用すると、対応するオブジェクトのハンドルにポインタを簡単に復元できますが、ポインタまたはハンドルを使用して、対応するポインタを簡単に変更できます。重要なのは、実際、ハンドルは単純な型のintであり、ロックフリーキューキューを介してプロセスによって別のプロセスに簡単にプッシュできるため、プロセス間でデータを効率的に共有するという目的を達成することです。ハンドル+ロックフリー::キューに基づいてプロセス間データ転送を完了することを見てみましょう。

(1)。構造のプロセス間でデータを共有する必要がある簡単な定義

#ifndef __IPC_HANDLE_DATA_H__ #define __IPC_HANDLE_DATA_H__ #include #include #include namespace bip = boost :: interprocess // to set the alias ipc // First define the type of shared memory allocator typedef bip::allocator CharAllocator typedef bip::basic_string shared_string // for IPCHandle transmission class IPCHandleData { public: IPCHandleData(const shared_string::allocator_type& al) ~IPCHandleData() int id __int64 id64 shared_string name } #endif

データ型には、id、id64、nameの3つのフィールドが含まれます

(2)使用する必要のある共有メモリハンドルタイプの定義、および必要な共有メモリ割り当てタイプのロックフリーキューキューの定義

// define the type of shared memory handle typedef bip::managed_shared_memory::handle_t IPCHandleT // define the handle of the shared memory allocator typedef bip::allocator MyIPCHandleAllocatorT // definition is based on the IPCHandle and corresponding memory allocator Queue typedef boost::lockfree::queue IPCHandleMwMrQueueT

(3)共有メモリの作成を担当する作成者(作成者)で構成され、送信用のロックフリーキューを作成します

void Creator() { cout << 'Creator' << endl // delete the legacy of shared memory bip::shared_memory_object::remove('MySharedMemory') // build a new hosting shared memory area bip::managed_shared_memory segment(bip::create_only, 'MySharedMemory', //segment name 65536 * 1024 * 10) // Define distributor hosting the shared memory area const MyIPCHandleAllocatorT alloc_inst(segment.get_segment_manager()) try { // create a shared memory for passing IPCHandleT lock-free queue IPCHandleMwMrQueueT *pMyIPCHandleQueue = segment.construct('MyIPCHandleQueue')(alloc_inst) } catch (exception &e) { cout << e.what() << endl } cout << 'Creator is waiting here...' << endl system('pause') }

(4)共有メモリとして最初のプロデューサーに接続

さらに、対応するロックフリーキューを見つけます。共有メモリハンドルベースのハンドル、送信する共有メモリオブジェクトを作成し、共有メモリオブジェクト、ロックフリーキューへのハンドルへのハンドルを見つけるために、転送操作が完了します

void Producer() { cout << 'Producer' << endl // attachment goal shared memory bip::managed_shared_memory segment(bip::open_only, 'MySharedMemory') //segment name typedef std::pair ResultT ResultT res = segment.find('MyIPCHandleQueue') cout << 'res.second=' << res.second << endl if (!res.second) { cout << 'could not find 'MyIPCHandleQueue'' << endl return } else { cout << 'find 'MyIPCHandleQueue'' << endl } IPCHandleMwMrQueueT *pMyIPCHandleQueue = res.first int id = 1 // Create an anonymous shared memory object, destroyed when needed destroy_ptr IPCHandleData *pIPCHandleData = segment.construct (bip::anonymous_instance) (shared_string::allocator_type(segment.get_segment_manager())) pIPCHandleData->id = id pIPCHandleData->id64 = id stringstream ss ss << 'name-'