プロセス間で文字列のスタックを共有する必要があります。私はboost :: interprocessを使うことに決めましたが、動かすことができません。私は何かを理解していないからだと確信しています。私はその例を踏襲しましたが、そのライブラリを使った経験がある人が自分のコードを見て、何が間違っているのかを教えていただければ幸いです。問題はうまくいくようですが、何度か反復した後は、読者プロセスと時にはライタープロセスの両方であらゆる種類の例外が発生します。 named_mutexを使用するように編集ブースト、共有メモリ、およびベクトル
using namespace boost::interprocess;
class SharedMemoryWrapper
{
public:
SharedMemoryWrapper(const std::string & name, bool server) :
m_name(name),
m_server(server)
{
if (server)
{
named_mutex::remove("named_mutex");
shared_memory_object::remove(m_name.c_str());
m_segment = new managed_shared_memory (create_only,name.c_str(),65536);
m_stackAllocator = new StringStackAllocator(m_segment->get_segment_manager());
m_stack = m_segment->construct<StringStack>("MyStack")(*m_stackAllocator);
}
else
{
m_segment = new managed_shared_memory(open_only ,name.c_str());
m_stack = m_segment->find<StringStack>("MyStack").first;
}
m_mutex = new named_mutex(open_or_create, "named_mutex");
}
~SharedMemoryWrapper()
{
if (m_server)
{
named_mutex::remove("named_mutex");
m_segment->destroy<StringStack>("MyStack");
delete m_stackAllocator;
shared_memory_object::remove(m_name.c_str());
}
delete m_mutex;
delete m_segment;
}
void push(const std::string & in)
{
scoped_lock<named_mutex> lock(*m_mutex);
boost::interprocess::string inStr(in.c_str());
m_stack->push_back(inStr);
}
std::string pop()
{
scoped_lock<named_mutex> lock(*m_mutex);
std::string result = "";
if (m_stack->size() > 0)
{
result = std::string(m_stack->begin()->c_str());
m_stack->erase(m_stack->begin());
}
return result;
}
private:
typedef boost::interprocess::allocator<boost::interprocess::string, boost::interprocess::managed_shared_memory::segment_manager> StringStackAllocator;
typedef boost::interprocess::vector<boost::interprocess::string, StringStackAllocator> StringStack;
bool m_server;
std::string m_name;
boost::interprocess::managed_shared_memory * m_segment;
StringStackAllocator * m_stackAllocator;
StringStack * m_stack;
boost::interprocess::named_mutex * m_mutex;
};
EDIT:ここに私の実装の簡易版です。元のコードは、間違っているinterprocess_mutexを使用していましたが、それは問題ではありませんでした。
EDIT2私はまた、ポイントまで機能することに注意する必要があります。ライタープロセスは、リーダが破損する前にいくつかの小さな文字列(または非常に大きな文字列)を押すことができます。リーダは、m_stack-> begin()行が有効な文字列を参照しないように分割します。それはごみです。そしてさらに実行すると例外がスローされます。
EDIT3クラスをstd :: stringではなくboost :: interprocess :: stringを使用するように変更しました。それでも読者は無効なメモリアドレスで失敗します。ここにリーダ/ライターです
//reader process
SharedMemoryWrapper mem("MyMemory", true);
std::string myString;
int x = 5;
do
{
myString = mem.pop();
if (myString != "")
{
std::cout << myString << std::endl;
}
} while (1); //while (myString != "");
//writer
SharedMemoryWrapper mem("MyMemory", false);
for (int i = 0; i < 1000000000; i++)
{
std::stringstream ss;
ss << i; //causes failure after few thousand iterations
//ss << "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" << i; //causes immediate failure
mem.push(ss.str());
}
return 0;
以前のポスターには大変申し訳ありません。私は間違って「削除」をクリックし、まったく同じ質問の元の投稿を消去しました。 – Budric
元に戻すことはできませんか?それともそれは答えのためだけに働くのですか? –
私はあなたのインラインメソッドのサイズでギャグを許可していますか?それとも、C++のnoobとしてマークしていますか? –