使用boost interprocess(v 1.41,1.44)x86_64共享字符串数据时的非Null-Terminated字符串

时间:2012-05-01 19:21:35

标签: c++ linux gcc boost boost-interprocess

我花了一些时间来搜索提升进程间文档,但我仍然被这个奇怪的错误所困扰。我已经看到这个代码工作在boost版本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版本上运行,而服务器端没有任何损坏。非常感谢!

P.S:当我使用托管共享内存功能时,我没有明确使用任何同步(互斥)机制。我一定要吗?

0 个答案:

没有答案