ブースト プロセス間ドキュメントを精査するのに時間を費やしましたが、この奇妙なバグに悩まされています。このコードがブースト バージョン 1.42、x86 で動作することを確認しましたが、タイトルに記載されているバージョンでは動作しません。
これは、文字列を共有する単純なクライアント サーバー モデルです。サーバーがセットアップされ、待機します。クライアントが新しい文字列をサーバーと共有すると、新しく共有された文字列が出力されます。コードは次のとおりです。
サーバ:
//compile this with: g++ -g server.cc -o server -lrt -lboost_thread-mt -lpthread -lcurses
#include <boost/interprocess/containers/string.hpp>
#include <boost/interprocess/containers/map.hpp>
#include <boost/interprocess/allocators/allocator.hpp>
#include <boost/interprocess/managed_shared_memory.hpp>
#include <cassert>
#include <boost/interprocess/containers/vector.hpp>
#include <iostream>
#include<curses.h>
#include<unistd.h>
using namespace std;
using namespace boost::interprocess;
int main()
{
typedef boost::interprocess::allocator<char, managed_shared_memory::segment_manager> CharAllocator;
typedef boost::interprocess::basic_string<char, std::char_traits<char>, CharAllocator> opString;
typedef boost::interprocess::allocator<opString, managed_shared_memory::segment_manager> StrAlloc;
typedef vector<opString, StrAlloc> opStringVector;
struct shm_remove
{
shm_remove() { shared_memory_object::remove("opSHM"); }
~shm_remove(){ shared_memory_object::remove("opSHM"); }
} remover;
managed_shared_memory managed_shm(open_or_create, "opSHM", 1000);
CharAllocator charallocator (managed_shm.get_segment_manager());
StrAlloc stralloc(managed_shm.get_segment_manager());
opStringVector * ID_Descript = managed_shm.construct<opStringVector>("ID_DESCRIPTOR")(stralloc);
opStringVector * ID_Handle = managed_shm.construct<opStringVector>("ID_HANDLE")(stralloc);
std::string serD = "This is the server";
std::string serI = "SERVER";
opString st1(charallocator);
opString st2(charallocator);
st1 = serD.c_str();
st2 = serI.c_str();
ID_Descript->push_back(st1);
ID_Handle->push_back(st2);
int i=0;
initscr(); //in ncurses
timeout(0);
int lastSize = 0;//ID_Handle2->size();
printw("\n Registration List: \n");
while(!i)
{
usleep(10000);
i=getch();
if(ID_Handle->size()!=lastSize)
{
for(int j = lastSize;j<ID_Handle->size();j++)
{
const char * hand_st = ID_Handle->at(j).c_str();
const char * desc_st = ID_Descript->at(j).c_str();
std::string hID = hand_st;
std::string dID = desc_st;
std::string newstr = "New process registered: " + hID + "\t" + dID;
const char * st = newstr.c_str();
printw("%s \n",st);
}
lastSize = ID_Handle->size();
}
if(i>0)
i=1;
else
i=0;
}
endwin();
}
クライアント:
//Compile this with: g++ -g client.cc -o client -lrt -lboost_thread-mt -lpthread -lcurses
#include <boost/interprocess/containers/string.hpp>
#include <boost/interprocess/containers/map.hpp>
#include <boost/interprocess/allocators/allocator.hpp>
#include <boost/interprocess/managed_shared_memory.hpp>
#include <cassert>
#include <boost/interprocess/containers/vector.hpp>
#include <iostream>
#include<curses.h>
#include<unistd.h>
using namespace std;
using namespace boost::interprocess;
int main()
{
typedef boost::interprocess::allocator<char, managed_shared_memory::segment_manager> CharAllocator;
typedef boost::interprocess::basic_string<char, std::char_traits<char>, CharAllocator> opString;
typedef boost::interprocess::allocator<opString, managed_shared_memory::segment_manager> StrAlloc;
typedef vector<opString, StrAlloc> opStringVector;
managed_shared_memory managed_shm(open_only, "opSHM");
CharAllocator charallocator (managed_shm.get_segment_manager());
StrAlloc stralloc(managed_shm.get_segment_manager());
opStringVector * ID_Descript2 = managed_shm.find<opStringVector>("ID_DESCRIPTOR").first;
opStringVector * ID_Handle2 = managed_shm.find<opStringVector>("ID_HANDLE").first;
opString st1(charallocator);
opString st2(charallocator);
std::string des;
std::string handle;
des = "A Dummy registration";
handle = "DU";
st1 = des.c_str();
st2 = handle.c_str();
ID_Descript2->push_back(st1);
ID_Handle2->push_back(st2);
cout << ID_Descript2->back() << '\t' << ID_Handle2->back() << endl;
des = "Null Algorithm\0";
handle = "OP_NULL";
st1 = des.c_str();
st2 = handle.c_str();
ID_Descript2->push_back(st1);
ID_Handle2->push_back(st2);
cout << ID_Descript2->back() << '\t' << ID_Handle2->back() << endl;
des = "First Algorithm";
handle = "OP_ALG_FIRST";
st1 = des.c_str();
st2 = handle.c_str();
ID_Descript2->push_back(st1);
ID_Handle2->push_back(st2);
cout << ID_Descript2->back() << '\t' << ID_Handle2->back() << endl;
des = "Last Algorithm";
handle = "OP_ALG_LAST";
st1 = des.c_str();
st2 = handle.c_str();
ID_Descript2->push_back(st1);
ID_Handle2->push_back(st2);
cout << ID_Descript2->back() << '\t' << ID_Handle2->back() << endl;
}
これはサーバー出力です:
Registration List:
New process registered: SERVER This is the server
New process registered: DU A Dummy registration
New process registered: OP_NULL Null AlgorithmTver
New process registered: OP_ALG_FIRST First AlgorithmAtion
New process registered: OP_ALG_LAST Last Algorithm
これはクライアント出力です:
A Dummy registration DU
Null Algorithm OP_NULL
First Algorithm OP_ALG_FIRST
Last Algorithm OP_ALG_LAST
ご覧のとおり、サーバーは文字列データを取得しますが、文字列の終端が正しくないため、出力に余分な/重複する文字が出力されます (4 行目と 5 行目)。クライアント側のデータは破損していません。他に何か重要なことが行われていないのではないかと思います。これに関する指針をいただければ幸いです。サーバー側で破損することなく、Boost 1.42 x86 バージョンでどのように動作するかも奇妙です。どうもありがとう!
PS: マネージド共有メモリ機能を使用しているため、同期 (mutex) メカニズムを明示的に使用していません。やらなくてはいけませんか?